不会写...看的题解,wsfw
物品的两个属性不太好弄
假如暴力设计状态,就是定义表示在
中
且
的状态是否存在
暴力枚举的话复杂度上天
换种思路
考虑到最后的合法方案是
也就是
不妨给所有扩大到
,这样一来我们只需要关注当前选择两种属性的偏移量
如果偏移量为零,那么达到目的
因为
所以偏移量不会超过这么多,再算上个物品
实现复杂度和空间复杂度最坏是
定义为前
个物品的偏移量为
时最大的
问题得到解
注意一下这个背包的物品由于有正数有负数,所以不能只开一维
(假如只开一维,需要分物品价值正数和负数分两次转移)
#include <bits/stdc++.h>
using namespace std;
const int base = 10000;
int n,k,f[109][20009],a[109],b[109];
signed main()
{
cin >> n >> k;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++) cin >> b[i];
memset( f,-0x3f,sizeof f);
int inf = f[0][0];
f[0][base] = 0;
for(int i=1;i<=n;i++)
{
int pian = a[i]-b[i]*k;
for(int j=-base;j<=base;j++)
{
if( j-pian+base<=20000&&j-pian+base>=0 )
f[i][j+base] = max( f[i-1][j+base],f[i-1][j-pian+base]+a[i] );
}
}
if( f[n][base]==0 ) f[n][base] = -1;
cout << f[n][base];
} 
京公网安备 11010502036488号