題目大意:給定n,k,用1-k組成n,一共有多少組合方法?
分析:
這題屬於完全部分和問題,其實也可以理解為劃分數問題。如n為3,k為2時,有
1+21+1+1 這2種方法,我們可以理解為用1和2去填滿或者組成3,這樣想便是完全揹包可行性也就是完全部分和問題。
或者這樣看,
1|11
1|1|1 這樣的話便是乙個劃分數問題,即將n個1劃分組且每組最多k個的問題,利用逆向思想,我們常常將劃分數問題轉化為完全部分和問題來求解(即劃分與組合是個可逆的過程)。
狀態:dp[i][j]前i種物品(1-i**)花費j元的種數
決策:第i種不買或者至少買乙個
轉移:不買的話顯然為dp[i-1][j]
至少買乙個的話為dp[i][j-i](注意與多重問題的區別,想一想為什麼)
所以 dp[i][j] = dp[i-1][j] + dp[i][j-i],最終提交還是錯了,自己輸出一些資料測試發現出現了不正常的數說明很有可能溢位了,可是如果寫乙個高精度的話肯定是要tle的。在網上看到一種很巧妙的方法,由於最大結果也只有33位(別人說的。。),long long可以儲存19位,所以可以利用2個long long來存乙個33位+的數,具體實現也很簡單,直接看**吧。
附上**:
#includeusing namespace std;
int n, k;
long long mod = 1;
long long dp1[1005], dp2[1005];
int main()
else
}if (dp1[n]) printf("%lld", dp1[n]);
printf("%lld\n", dp2[n]);
return 0;
}
POJ 3181 完全揹包
題意 farmer john 想知道,在一家商品 為1至k 1 k 100 的店有多少方法能正好花完他的n 1 n 1000 元錢 商品數量充足。思路 完全揹包,dp j 表示 為j時花光錢的方法數,所以狀態轉移方程為dp j dp j i i為商品 因為方法數過大超longlong了,所以開兩個l...
經典揹包問題 01揹包 完全揹包 多重揹包
1 for int i 0 i 2for int j w j size i j 3 f j max f j f j size i value i 1 for int i 0 i 2for int j size i j w j 3 f j max f j f j size i value i f w ...
POJ 1384 完全揹包
題意 給定乙個重量,和各種錢幣的重量,求可以滿足給定重量的錢幣組合中的最小組合。如果存在組合就求出最小值。轉移方程 1 f j 和 f j w i 都可達 則 f j min 2 f j 不可達 但 f j w i 可達 則 f j f j w i p i 3 其餘情況 則不作處理 程式 inclu...