http://codeforces.com/contest/366/problem/C
题目要求a的和为b的和的k倍,就是说最后要达到的状态为ai1+ai2+ai3+ai4==kbi1+kbi2+kbi3+kbi4……
不妨设ai=k*bi+c,c=k*bi-ai; 这里的c表示如果选了这组,那么还差多少才能满足题意。很显然,最后得到的结果中,所有的c的和应该为0.
定义dp[i]表示还差 i 可以满足题意时 最大能达到的 a (taste值)。
dp[j]=max(dp[j] , dp[j-c[i]]+a[i]);
注意c可能为正也可能为负,为了不使某一个fruit被重复加两次,可以开二维数组来做,也可以先判断c的正负,再根据正负来写 j 的遍历顺序,这样只用一维数组。
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define inf 2147480000
int n,k;
int dp[101][20002];
int box[101];
int aox[101];
int cox[101];
int main(int argc, char *argv[])
{
cin>>n>>k;
memset(dp,-1,sizeof(dp));
for(int i=1;i<=n;i++)
cin>>aox[i];
for(int i=1;i<=n;i++)
cin>>box[i];
for(int i=1;i<=n;i++)
cox[i]=k*box[i]-aox[i];
dp[0][10000]=0;
for(int i=1;i<=n;i++)
{
for(int j=20000;j>=0;j--)
{
if(j-cox[i]>=0 && j-cox[i]<=20000)
{
if(dp[i-1][j-cox[i]]!=-1)
{
dp[i][j]=max(dp[i][j],dp[i-1][j-cox[i]]+aox[i]);
}
}
dp[i][j]=max(dp[i-1][j],dp[i][j]);
}
}
if(dp[n][10000]!=0)
cout<<dp[n][10000]<<endl;
else
cout<<-1<<endl;
return 0;
}