题目链接。
分析:
该题为多重背包。
有了上一次的经验(HDU2191),这道题也就了了了。
本题的思路:
将cash想象成包的容量,将面值Dk想象成两个条件,即体积和价值都为Dk,那么本题就自然而然的成了求最大价值的问题。
另外,这次尝试了一下其它的代码风格,因为曾经听说过,试了一下,写起来感觉不错,但找起来错就不那么容易了。
纠结#define For(i, i0, n) for(int i=i0; i<=n; i++),是将它定义成i<=n呢还是i<n呢?在敲代码的过程中错认为是i<n,找了很久BUG。
#include <cstdio> #include <cstring> #include <cstdlib> #define For(i, i0, n) for(int i=i0; i<=n; i++) #define Forx(i, n, i0) for(int i=n; i>=i0; i--) #define scad(n) scanf("%d", &n) #define scas(s) scanf("%s", s) #define Memset(p) memset(p, 0, sizeof(p)) int dp[100010]; int main(){ int cash, n, p, d; while(scad(cash) == 1){ For(i, 0, cash) dp[i] = 0; scad(n); For(i, 0, n-1){ scad(d); scad(p); if(d * p >= cash){ For(j, 0, cash){ if(j+p<=cash && dp[j+p] < dp[j]+p) dp[j+p] = dp[j]+p; } } else{ int k=1; while(d){ if(k > d) k = d; d -= k; Forx(j, cash, k*p){ if(dp[j] < dp[j-k*p]+k*p) dp[j] = dp[j-k*p]+k*p; } k <<= 1; } } } printf("%d\n", dp[cash]); } }