pku1276 Cash Machine (DP)

动态规划,n个数的线性组合

注意其中的逆序更新, flag[i]表示这n个数的线性组合结果能否为i

每次更新从0到end之间的部分

#include <iostream> using namespace std; /* #include <fstream> ifstream fin("data.txt"); #define cin fin */ int dk[11], nk[11], n, cash; bool flag[100001]; int main() { int i, j, k, ans, end; while (cin>>cash>>n) { for (i=0; i<n; i++) cin >> nk[i] >> dk[i]; memset(flag, 0, sizeof(flag)); flag[0] = true; end = 0; for (i=0; i<n; i++) { for (j=end; j>=0; j--) //必须倒序更新 { if (flag[j]) { for (k=1; k<=nk[i]; k++) { if (j+k*dk[i]>cash || flag[j+k*dk[i]]) //这个剪枝很重要 break; flag[j+k*dk[i]] = true; } } } end += nk[i]*dk[i]; if (end>cash) end = cash; } ans = cash; while (!flag[ans] && ans>=1) ans--; cout << ans << endl; } return 0; }

你可能感兴趣的:(pku1276 Cash Machine (DP))