1. 程式人生 > >[pat]1068 Find More Coins

[pat]1068 Find More Coins

fill spa 問題 namespace esp 排序 main pac --

滿背包問題,把體積和價值看成相等的。用滾動數組優化,然後額外開辟一個choice數組來記錄每次的選擇,然後回溯打印。因為要按字典序,先把價值進行排序。假如選最小的商品能裝滿m的話,那就把判斷條件改成大於等於,然後最後來

#include<bits/stdc++.h>
using namespace std;
int dp[105];
int w[10005];
bool flag[10005];
bool choice[10005][105];
int n, m;
bool cmp(int a, int b)
{
    return a > b;
}
int main()
{
    memset(flag, 
false, sizeof(flag)); fill(choice[0], choice[0] +105, false); fill(dp, dp +105, 0); scanf("%d %d", &n, &m); int i, j; for (i = 1; i <= n; i++) { scanf("%d", &w[i]); } sort(w+1, w + n+1,cmp); for (i = 1; i <= n; i++) { for (j = m; j >= w[i]; j--) {
if (dp[j-w[i]]+w[i]>=dp[j]) { dp[j] = dp[j - w[i]] + w[i]; choice[i][j] = true; } } } int x=n, y=m; int num = 0; if (dp[m] != m) { printf("No Solution\n"); } else { while (x >= 1) {
if (choice[x][y] == true) { flag[x] = true;//下標 num++; y -= w[x]; } x--; } for (i = n; i >= 1; i--) { if (flag[i] == true) { if (num - 1 > 0) { printf("%d ", w[i]); num--; } else printf("%d\n", w[i]); } } } }

選擇最小的那個。

[pat]1068 Find More Coins