第一次接触完全背包,看了别人思路后再写的。
关于本题的背包问题的几个总结:
1. 注意分析全面转移条件,有时候这个问题会卡住
2. 这题的背包是每个物品有限个,本题中用cnt[]在转移条件中限制
3. 学会将问题转化,例如本题一开始想不到用背包,考虑用搜索如果真的搜索的话效率一定低下,但要求是硬币数最多的组合,就能用背包了
4. 通过Pre[]记录路径的方法很有意思
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 10010
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
int price;
int Num[4];//记录对应硬币数量
int Pre[N];//路径记录
int dp[N];//记录上一轮的结果
int cnt[N];//记录算到某个物品的每个价格可能的装的个数
int ans[30];//反求路径时记录回答
int val[4] = {1, 5, 10, 25};
int main(){
while(~scanf("%d%d%d%d%d", &price, Num, Num+1, Num+2, Num+3)){
if(!price && !Num[0] && !Num[1] && !Num[2] && !Num[3]) break;
mem(dp, -1);
mem(Pre, 0);
dp[0] = 0;
Pre[0] = -1;
for(int i=0; i < 4; i+