
#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 301; int c1[MAXN], c2[MAXN]; int main() { int n; while (scanf("%d", &n) && n) { for (int i = 0; i <= n; ++i) c1[i] = 1, c2[i] = 0; for (int i = 2; i <= 17; ++i) { for (int j = 0; j <= n; ++j) for (int k = 0; k + j <= n; k += i*i) c2[j+k] += c1[j]; for (int j = 0; j <= n; ++j) c1[j] = c2[j], c2[j] = 0; } printf("%d\n", c1[n]); } return 0; }
HDOJ 1028 ( Ignatius and the Princess III )

#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 125; int c1[MAXN], c2[MAXN]; int main() { int p; while (scanf("%d", &p) != EOF) { for (int i = 0; i <= p; ++i) c1[i] = 1, c2[i] = 0; for (int i = 2; i <= p; ++i) { for (int j = 0; j <= p; ++j) for (int k = 0; k + j <= p; k += i) c2[j+k] += c1[j]; for (int j = 0; j <= p; ++j) c1[j] = c2[j], c2[j] = 0; } printf("%d\n", c1[p]); } return 0; }
HDOJ 1085 ( Holding Bin-Laden Captive! )

#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 10010; int c1[MAXN], c2[MAXN]; int main() { int num1, num2, num5; while (scanf("%d %d %d", &num1, &num2, &num5)) { if (!num1 && !num2 && !num5) break; memset(c1, 0, sizeof(c1)); memset(c2, 0, sizeof(c2)); //int maxsum = num1 + 2 * num2 + 5 * num5; for (int i = 0; i <= num1; ++i) c1[i] = 1; int num[3], cnt[3]; num[0] = 2; cnt[0] = num2; num[1] = 5; cnt[1] = num5; int sum = num1; for (int i = 0; i < 2; ++i) { for (int j = 0; j <= sum; ++j) for (int k = 0; k <= cnt[i]; ++k) c2[j+k*num[i]] += c1[j]; sum += num[i] * cnt[i]; for (int j = 0; j <= sum; ++j) c1[j] = c2[j], c2[j] = 0; } int i; for (i = 1; i <= sum; ++i) if (!c1[i]) break; printf("%d\n", i); } return 0; }
HDOJ 1171 ( Big Event in HDU )
其实这题和上题1085一样的思路,用母函数解决。但是觉得这样没意思,于是用多重背包解决了下,顺便练练手
思路:
假设背包容量为总的价值的一半,那这个容量能拿到的价值则是输出的2个价值之一

#include <cstdio> #include <cstdlib> #include <cstring> #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) int v[51], m[51]; int dp[250005]; int main() { int n; while (scanf("%d", &n) && n > 0) { int sum = 0, val = 0; for (int i = 0; i < n; ++i) { scanf("%d %d", &v[i], &m[i]); sum += m[i]; val += v[i] * m[i]; } memset(dp, 0, sizeof(dp)); for (int i = 0; i < n; ++i) { int c = 1, j = m[i]; while (c <= j) { j -= c; for (int k = val>>1; k >= c * v[i]; --k) dp[k] = max(dp[k], dp[k-c*v[i]] + c*v[i]); c *= 2; } if (j > 0) for (int k = val>>1; k >= v[i] * j; --k) dp[k] = max(dp[k], dp[k-j*v[i]] + j*v[i]); } printf("%d %d\n", max(dp[val>>1], val - dp[val>>1]), min(dp[val>>1], val - dp[val>>1])); } return 0; }