POJ1018解题报告

http://poj.org/problem?id=1018

题目比较拗口,不过简单的理解就是。用户给定n行设备,这n行设备有m对,分别对应这个设备的带宽和价格。要求从这n行设备中每行选一个设备,使得B=min{bn1,bn2,...bnn},P=pn1+pn2+...+pnn,从而使得B/P得到最大。

我是看了别人的解题报告,用搜索+剪枝做的。

大概的思路如下:

首先,按从小到大的顺序,对所有的带宽进行排序。

如题:

1 3
3 100 25 150 35 80 25
2 120 80 155 40
2 100 100 120 110
那么得到的带宽排列为80、100、110、120和150.

然后从带宽为80开始,首先将minbrand设为80.再依次遍历每一行,初始时min=MAX_PRCICE,判断每一行中有没有设备brand>=minbrand且price<min。如果有,那么设found为true,并令min=price,否则,设found为false。

当found为false时,break,查找失败。进入下一轮循环。

当found为true时,sum+=min.

然后判断bp与minbrand/sum的大小关系。反复循环。

具体的代码如下,用G++编译器通过。(不过此代码有个缺陷,虽然能够AC,但不能保证brand等于minbrand的设备一定被选择了,之所以能够AC还是POJ的测试数据不够强的缘故。此缺陷有时间再完善。)

#include<iostream> #include<vector> #include<algorithm> using namespace std; int main() { int n; cin>>n; for(int i=0;i<n;i++) { int device; cin>>device; int **m=new int*[device]; int *h=new int[device]; for(int j=0;j<device;j++) { int temp; cin>>temp; m[j]=new int[2*temp]; h[j]=temp; for(int k=0;k<temp;k++) { cin>>m[j][2*k]; cin>>m[j][2*k+1]; } } //上面为获得输入 //获得所有不同的带宽(distinct) vector<int> myvector; for(int j=0;j<device;j++) { for(int k=0;k<h[j];k++) { myvector.push_back(m[j][2*k]); } } sort(myvector.begin(),myvector.end()); myvector.erase(unique(myvector.begin(),myvector.end()),myvector.end()); //遍历带宽 float bp=0; float sum=0; int minbrand; bool found=false; for(int j=0;j<myvector.size();j++) { sum=0; minbrand=myvector[j]; float min; for(int q=0;q<device;q++) { min=1000000; found=false; //cout<<strlen(m[j])<<endl; for(int w=0;w<h[q];w++) { if(m[q][2*w]>=minbrand&&m[q][2*w+1]<min) { min=m[q][2*w+1]; found=true; } } if(found==true) { sum+=min; } else { break; } } if(found) { if(((float)minbrand/sum)>bp) { bp=(float)minbrand/sum; } } } cout.setf(ios::fixed,ios::floatfield); cout.precision(3); cout<<bp<<endl; delete []m; delete h; } system("pause"); return 0; }

你可能感兴趣的:(ios,测试,delete,System,float,编译器)