0-1背包:
n道数学题分值为A[I] A[2] A[3].....A[N] 1<=A[i]<=100
求怎么拼凑得到100分,一共需要多少道题目,分别是哪些题目
输入:3 10 30 60 输出:3 1 2 3
int main(){
int n = 0;
while (cin >> n&&n>0){
vector<int> score(n, 0);
for (int i = 0; i < n; ++i){
cin >> score[i];
}
vector<int> dp(101, -1);//存放的是当前分值下最后一次放入的题目的编号
for (int i = 0; i < n; ++i){
for (int j = 100; j >= score[i]; --j){
if (j == score[i])
dp[j] = i;
else if (dp[j - score[i]] != -1){
dp[j] = i;
}
}
}
int sum = 100;
vector<int> result;
while (dp[sum] != -1){//回溯得到所有题目的编号
result.push_back(dp[sum]);
sum -= score[dp[sum]];
}
cout << result.size() << endl;
for (int i = result.size() - 1; i >= 0; --i){
cout << result[i] + 1 << endl;
}
}
return 0;
}
完全背包:
当前有1毛钱,2毛钱,5毛钱,1块钱问要得到10块钱共有多少种不同的组合方案
int money(vector<int>& moneys,int total){
vector<int> dp(total + 1, 0);//存放的是凑足j毛钱总共有几种组合方法
dp[0] = 1;
for (int i = 0; i < moneys.size(); ++i){
for (int j = moneys[i]; j <= total; ++j){
dp[j] += dp[j - moneys[i]];//凑足j的方法是没有考虑加入第i种面额的货币的方法数加上
//考虑加入第i种面额的货币的方法数
}
}
return dp[total];
}