poj1742(揹包)
阿新 • • 發佈:2018-11-02
一個揹包,當然正解是完全揹包,不過我用拆分法水過了。。
小於等於7的數可由1 2 4拼成
小於等於15的數可有1 2 4 8拼成
那麼對於7到15之間的數n
可有1 2 4 n-7拼成
運用這個思想把有限制的揹包轉化成0/1揹包就好了。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; bool isv[100020]; int a[120], c[120], allv[2200]; int tot; int n, m; int ans; int main() { while (scanf("%d%d", &n, &m)) { if (n == 0 && m == 0)break; tot = 0; ans = 0; for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } for (int i = 0; i < n; i++) { scanf("%d", &c[i]); } for (int i = 0; i < n; i++) { int temp = 0; int q = 1; allv[tot++] = a[i]; temp += q; while ((temp+q*2) < c[i]) { q *= 2; allv[tot++] = a[i] * q; temp += q; } if ((c[i] - temp) > 0) allv[tot++] = (c[i] - temp)*a[i]; } isv[0] = 1; for (int i = 0; i < tot; i++) { for (int j = m; j >= allv[i]; j--) { isv[j] = (isv[j - allv[i]] | isv[j]); } } for (int i = m; i >= 1; i--) { if (isv[i]) ans++; } printf("%d\n", ans); for (int i = 0; i <= m; i++) isv[i] = 0; } }