0-1背包之四

//sicily 1221. 数字游戏

//m个回合里,每个回合在n个数中选择一个ai,然后剩下的数都减去bi,求选中的ai之和的最大值
//0-1背包,每个数的体积都为1,背包容量为 m
//显然,如果选中的m个数已固定的话,擦去这m个数的顺序对结果有影响,很明显为最大化,应该先擦掉bi小的数,
//所以事先要排好序,按bi从大到小排,靠后dp选中的数bi较小

#include
<iostream> //0-1背包
#include<algorithm>
using namespace std;
struct node
{
int a,b;
}ans[
202];
bool cmp(const node& x,const node& y)
{
return x.b>y.b;
}
int n,m,dp[202];
int main()
{
cin
>>n>>m;
for(int i=0;i<n;++i)
cin
>>ans[i].a;
for(int i=0;i<n;++i)
cin
>>ans[i].b;
sort(ans,ans
+n,cmp);
for(int i=0;i<n;++i) //bi 逐渐减小
for(int j=m;j>0;--j)
dp[j]
=max(dp[j],dp[j-1]+ans[i].a-ans[i].b*(j-1)); //dp[j]表示 j 回合内能选中的ai最大总和
cout<<dp[m]<<endl;
return 0;
}

//状态转移方程: dp[j]=max(dp[j],dp[j-1]+ans[i].a-ans[i].b*(j-1));
//其中dp[j-1]+ans[i].a-ans[i].b*(j-1) 表示 j 回合内第一个数为 ai 的价值
//dp[j-1]是 ai 不参与的情况下, j-1 回合内的最大值,
//+ans[i].a-ans[i].b*(j-1) 是第一个数为 ai ,由于 bi 在 j 回合内是最小的,所以应最先擦掉,故要对余下的(j-1)数减去 bi

  

posted on 2011-08-22 11:44  sysu_mjc  阅读(124)  评论(0编辑  收藏  举报

导航