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];
}