您的位置:首页 > 理论基础 > 计算机网络

换角度思考:http://acm.hdu.edu.cn/showproblem.php?pid=3602

2010-11-25 02:38 453 查看
#include<iostream>
#include<cstdio>
using namespace std;
int dp[10001]; //dp[i]表示收益为i的最少能载的人数
int c[101],v[101];
int n,m,k;
const int INF=900000000;
int add(int a,int b)
{
if((a+b)/k==a/k||(a+b)%k==0) //如果a+b人所需船的数量跟a人所需的数量一样或者刚好坐满多出的一艘船
return a+b;
else
return (a/k+1)*k+b; //不然b人挤不下原来的船只说剩余的空位,只能另外找一艘船,这里关系的到同一个国家的人能否坐在同一艘船上,
//而且限制了每一艘船的人数,至于顺序限制,在转化方程中已经体现出来
}
int min(int a,int b)
{
return a>b?b:a;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
int i,j;
int max=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&c[i],&v[i]);
c[i]++; //president
max+=v[i];
}
for(i=0;i<=max;i++)
dp[i]=INF;
dp[0]=0;
for(i=0;i<n;i++)
{
if(c[i]>k)
continue;
for(j=max;j>=v[i];j--)
dp[j]=min(dp[j],add(dp[j-v[i]],c[i])); //最大收益=最小代价,与传统的0-1背包相反,思路一样
}
i=max;
while(dp[i]>k*m)
i--;
printf("%d/n",i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: