您的位置:首页 > 其它

366C - Dima and Salad(0-1 背包)

2013-11-26 22:03 246 查看
//0-1背包 比赛的时候想到c[i]=a[i]-b[i]*k的转化了 但是没想到用DP

//转化后就是一列数c[] 取其中的任意几个 让它们的和为0 并且所对应的a[]的和最大值

//c[i]的和的范围是-10000到10000

//dp[i][j]表示从前i个数中任意挑出几个数 和为j的状态的所对应a[]的和的最大值

//则dp
[0]就是从n个数中选出任意个它们的和为0 所对应的a[]的最大值

//但是数组的下标不能是负值 所以把dp[0][10000]当成0点

// 把c[]当成物品体积 a[]当成物品价值

#include<stdio.h>

#include<string.h>

#define max(a,b) a>b?a:b;

int n,k;

int dp[2][21000],a[110],b[110],c[110];

void init()

{

int i;

for(i=1;i<=n;i++)

{

scanf("%d",&a[i]);

}

for(i=1;i<=n;i++)

{

scanf("%d",&b[i]);

c[i]=a[i]-b[i]*k;

}

memset(dp,-1,sizeof(dp));

dp[0][10000]=0;

}

int Dp()

{

int i,j;

int f=0;

for(i=1;i<=n;i++)

{

f=f^1;

for(j=0;j<=20000;j++)

{

if(j-c[i]>=0&&j-c[i]<=20000)

{

dp[f][j]=max(dp[f][j],dp[1-f][j]);//把前一个状态移下来

if(dp[1-f][j-c[i]]!=-1)//0-1 背包

dp[f][j]=max(dp[f][j],dp[1-f][j-c[i]]+a[i]);

}

}

}

if(dp[f][10000])

return dp[f][10000];

return -1;

}

int main()

{

while(scanf("%d %d",&n,&k)!=EOF)

{

init();

int ans=Dp();

printf("%d\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: