View Code
//hdu 1114 dp(01背包) //题意为 用各种币种填满储蓄罐(有给出满是的质量),若能填满 //输出填满后的最小价值,若填不满则输出不可能 #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define INF 1<<28 #define N 10005 int empty, full; int dp[N], val[505], w[505]; int main() { int n_case; scanf("%d", &n_case); while(n_case--) { scanf("%d%d", &empty, &full); full -= empty; for(int i = 0; i <= full; ++i) dp[i] = INF; int n_curren; scanf("%d", &n_curren); for(int i = 0; i < n_curren; ++i) scanf("%d%d", &val[i], &w[i]); //转移方程 dp[i] = min{ dp[j], dp[j-w[i]] + val[j] } //表示从质量为 j-w[i] 的状态下向 质量为j 的状态转移时 //记录 质量为j 时的最小价值即可,若所有硬币中,所有质量组合中 //不能达到full 则 dp[full - w[i]] 到 dp[full] 就不可能转移成功 dp[0] = 0; //质量为0 时,即没放任何硬币时,价值为0 for(int i = 0; i < n_curren; ++i) for(int j = w[i]; j <= full; ++j)//从前往后推,质量累加上去,若能填满 dp[j] = min(dp[j], dp[j - w[i]] + val[i]); //则dp[full]就会被赋值 if(dp[full] == INF) puts("This is impossible."); else printf("The minimum amount of money in the piggy-bank is %d.\n", dp[full]); } }