题意:给出n个物品,有价值和花费,然后给出一个k。问从里边挑出一些物品,物品的价值比上花费等于k,求最大的价值,找不到输出-1。
思路:对于每一个物品,求出c = a - k * b,然后使得所有物品的c相加等于零就符合条件。这里当然是01背包,相当于n个c组成0,对应的a值相加的值最大。不过因为这里的c值有负数的情况,所以我们得分成正负两个dp,当他们相等的时候,即相加等于0;
#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn = 1e4 + 10; typedef long long ll; #define clr(x,y) memset(x,y,sizeof x) #define INF 0x3f3f3f3f const ll Mod = 1e9 + 7; typedef pair<int,int> P; int a[maxn],b[maxn]; int dp1[maxn * 10],dp2[maxn * 10]; int main() { int n,k; while( ~ scanf("%d%d",&n,&k)) { clr(dp1,-INF);clr(dp2,-INF); dp1[0] = dp2[0] = 0; for(int i = 1;i <= n;i ++) scanf("%d",&a[i]); for(int i = 1;i <= n;i ++) { scanf("%d",&b[i]); b[i] = a[i] - b[i] * k; } for(int i = 1;i <= n;i ++) { if(b[i] >= 0) for(int j = 10000;j >= b[i];j --) dp1[j] = max(dp1[j],dp1[j - b[i]] + a[i]); else { b[i] = - b[i]; for(int j = 10000;j >= b[i];j --) dp2[j] = max(dp2[j],dp2[j - b[i]] + a[i]); } } int ans = 0; for(int i = 0;i <= 10000;i ++) { ans = max(ans,dp1[i] + dp2[i]); } cout << (ans == 0 ? -1 : ans) << endl; } return 0; }