程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> uva - 11137 - Ingenuous Cubrency

uva - 11137 - Ingenuous Cubrency

編輯:C++入門知識

題意:用21種球幣:1^3, 2^3, ..., 21^3(數量不限)來組成數n來幾種方法。

——>>汝佳神牛白書動態規劃中通過率最高的一題,卻讓我搞了大半夜也沒弄出來,今早一試卻AC!

dp(i, j)表示用前i種球幣組成j元錢的方法數;

狀態轉移方程:dp(i, j) = dp(i-1, j) + dp(i, j-v[i]);(對於第i種球幣,要麼不用(dp(i-1, j))),要麼用(dp(i, j - v[i]))

之前一起數字一到9282就開始不對,因為是一次輸出:cout<<dp(21, i)<<endl;

後將前9999種錢數都先存入數組,便解決了這數大不對的問題,具體原因……(求解答)

[cpp] 
#include <iostream> 
#include <string.h> 
 
using namespace std; 
 
const int maxn = 10000 + 10;        //最大數不超過10000 
 
int v[30];      //用來存21種球幣  www.2cto.com
 
long long d[30][maxn];      //d[i][j]用來存用前i種球幣組成j元錢的方法數 
 
long long dp(int i, int j)      //動態規劃:前i種球幣組成j元錢的方法數 

    if(d[i][j] > 0) return d[i][j];     //如果已經記錄過了,直接返回 
    if(j < 0)   return 0;       //如果在dp(i, j-v[i])出現了j-v[i]<0的情況,返回0,不可能用正數的和來表示一個負數 
    if(i == 1 || j == 0)        //dp(i-1, j)必然出現i == 1的情況,用面值為1的球幣表示任一正數,只有1種方法,可能出現j-v[i] == 0,說明那種面值的球幣恰能一次表示,也記1種方法 
    { 
        d[i][j] = 1; 
        return 1; 
    } 
 
    d[i][j] = dp(i-1, j) + dp(i, j-v[i]);       //狀態轉移,前於第i種球幣,要麼不用,要麼用 
 
    return d[i][j]; 

 
int main() 

    int i; 
    for(i = 1; i <= 21; i++)        //設置21種球幣 
        v[i] = i * i * i; 
 
    memset(d, 0, sizeof(d));        //置-1,用來標記有沒被修改過 
 
    for(i = 1; i < 10000; i++)      //先將前9999元的情況存入數組 
        dp(21, i); 
 
    while(cin>>i) 
    { 
        cout<<d[21][i]<<endl;       //直接從數組中讀出 
    } 
 
    return 0; 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved