题目地址:点击打开链接
姿势水平太低啊。。。看到题是根本没思路
思路粘自:点击打开链接
题目要求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<bits/stdc++.h>
using namespace std;
const int maxn = 1e2+5;
const int maxm = 1e4+5;
const int INF = 0x3f3f3f3f;
int n, k, a[maxn], b[maxn], dp1[maxm], dp2[maxm];
int main(void)
{
while(cin >> n >> k)
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
scanf("%d", &b[i]);
memset(dp1, -INF, sizeof(dp1));
memset(dp2, -INF, sizeof(dp2));
dp1[0] = dp2[0] = 0;
for(int i = 1; i <= n; i++)
{
int c = a[i]-b[i]*k;
if(c >= 0)
{
for(int j = 10000; j-c >= 0; j--)
dp1[j] = max(dp1[j], dp1[j-c]+a[i]);
}
else
{
for(int j = 10000; j-(-c) >= 0; j--)
dp2[j] = max(dp2[j], dp2[j-(-c)]+a[i]);
}
}
int ans = 0;
for(int i = 0; i <= 10000; i++)
ans = max(ans, dp1[i]+dp2[i]);
printf("%d\n", ans ? ans : -1);
}
return 0;
}