bzoj1531
背包+倍增
直接背包跑不过去,那么我们把容量分成二进制,然后原来需要枚举c次就只用枚举log(c)次了,这样还是能组合出任意小于等于c的组合方案
#include<bits/stdc++.h> using namespace std; const int N = 20010; int n, s; int b[N], c[N], dp[N]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &b[i]); for(int i = 1; i <= n; ++i) scanf("%d", &c[i]); scanf("%d", &s); memset(dp, 0x3f3f, sizeof(dp)); dp[0] = 0; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= c[i]; j <<= 1) { for(int k = s; k >= j * b[i]; --k) dp[k] = min(dp[k], dp[k - j * b[i]] + j); c[i] -= j; } if(c[i]) for(int j = s; j >= c[i] * b[i]; --j) dp[j] = min(dp[j], dp[j - c[i] * b[i]] + c[i]); } printf("%d\n", dp[s]); return 0; }