就類似完全揹包。。不過要恰好等於揹包容量。。
就是給n種數ai,各mi個,判斷是否能從這些數字中選出若干個使他們的和為v。
用dp求解,dp[i+1][j]表示前i種數字能否加和得到j。dp[i+1][j] 只要dp[i][j-k*ai]有乙個為真那麼就為真。(0<=k<=mi)
**:
#include #include #include #include using namespace std;
#define m 109
int a[m],m[m];
bool dp[m][100009];
int main()
}if(dp[n][v]) printf("yes\n");
else printf("no\n");
}return 0;
}
這樣可以看出時間複雜度為o(v*(m1+```+mi))
書上說用dp陣列只用來求bool結果,會造成浪費。給出了乙個優化,dp[i+1][j]表示前i種數字中加和為j後還剩下幾個第i種數字(如果不能加和為j 就為-1)
當dp[i][j]>=0時,dp[i+1][j] = mi 當dp[i+1][j-ai]<=0或者j給出**:
#include #include #include #include using namespace std;
#define m 109
int a[m],m[m];
int dp[m][100009];
int main()
return 0;
}
優化成一維:
#include #include #include #include using namespace std;
#define m 109
int a[m],m[m];
int dp[100009];
int main()
return 0;
}
挑戰程式設計競賽 部分和問題
1 這道題的揹包思想 2 這道題的深度優先搜尋思想 複雜度 2 比較,很明顯,對這道題,深度優先搜尋更佔優勢。include includeusing namespace std const int offset 1000 const int maxn 21 const int maxm maxn ...
《挑戰程式設計競賽(六)》DP解法 多重部分和問題
題目如上所示 按著前面題目的思路,完成如下 關鍵思路是遞推式要不斷取或 按照書上的習慣,先把輸入條件標出來,然後寫solve函式,這樣比較清爽 include include using namespace std define max n 100 define max k 100000 int n...
程式設計訓練 多重部分和問題
給定n個不同大小的數字a ia i ai 每種數字個m im i mi 個,判斷是否可以從這些數字中選出若干數是的它們的和恰好為k。樣例輸入3 3 5 8 3 2 2 17這個樣例輸入的意思是一共有三種數字,分別是3 5 8,每個數字的個數分別是3 2 2.即從3個3 2個5 2個8中是否能找出乙個...