poj 1018

来源:互联网 发布:淘宝信誉最差的店 编辑:程序博客网 时间:2024/05/29 03:04

在DP专题里做的,后来看别人的解题报告,发现其实还可以用贪心做。。。(其实也就是把DP优化了结果)

 

题意:

有n种装备,每种装备有m种供应商,每个装备有两个性质:带宽以及价值;

现选出n种装备,那么,总装备的带宽为n种装备的最小值,价值为n个装备的价值和

怎样选,使n个装备的总带宽与总价值的比最大。

 

这道题的题意光是理解就理解了半天。。。纠结啊~

dp[i][j]的含义:选择到第i种装备,当带宽最小为j时,价值的最小值;

由于对于选中的装备,j 的值为带宽最小值,所以对于其他的带宽,其值都不能小于这个最小值j,如果小于的话,那么最小的带宽就要被替换。

转移方程:

d[i][j]:第i种装备的j个产品的带宽;

p[i][j]:第i种装备的j个产品的价值;

dp[i][min(j,d[i][k])]=min(dp[i][min(j,d[i][k])],dp[i-1][j]+p[i][k]);

 

代码:

 

#include<iostream>#include<string.h>#include<stdio.h>#include<fstream>using namespace std;int dp[105][10005];int d[105][105];int p[105][105];int num[105];int main(){        // freopen("1018in.txt","r",stdin);        // freopen("1018out.txt","w",stdout);         int n;         cin>>n;         while(n--){            int m;            cin>>m;            int maxb=0;            for(int i=0;i<m;i++){                  int temp;                  cin>>num[i];                  for(int j=0;j<num[i];j++){                           cin>>d[i][j]>>p[i][j];                           if(maxb<d[i][j])                                    maxb=d[i][j];                  }            }            for(int g=0;g<=m;g++){               for(int k=0;k<=maxb;k++){                  dp[g][k]=1000000000;               }            }            for(int i=0;i<num[0];i++){                  dp[0][d[0][i]]=p[0][i];            }            for(int i=1;i<m;i++){                  for(int j=0;j<=maxb;j++){                           for(int k=0;k<num[i];k++){                                    dp[i][min(d[i][k],j)]=min(dp[i-1][j]+p[i][k],dp[i][min(d[i][k],j)]);                           }                  }            }            double res=0;            for(int k=0;k<=maxb;k++){                  if(res<k*1.0/dp[m-1][k])                           res=k*1.0/dp[m-1][k];            }            printf("%.3lf\n",res);            //cout<<res<<endl;         }         return 0;}


 

 

原创粉丝点击