題意:給定乙個long long型別能夠存下的數字n,統計1~n之間含有49的數字的個數;
思路:初始版本:需要記錄當前位置,前一位置放了那個數字,當前是否已經包含49,是否有上界這四個資訊,也就是dfs的四個引數。dfs(pos,pre,istrue,limit);
其實這種做法有點相當於把普通的數字dp的求dp過程和最後總計的過程合二為一了。
[cpp]view plain
copy
print?
#include
#include
using
namespace std;
int t;
long
long n;
long
long dp[25][12][2];
int d[25],len;
long
long dfs(int pos,int pre,int flag,bool limit)
long
long solve(long
long n)
return dfs(len,0,0,true);
} int main()
return 0;
}
仔細想一下dp陣列為什麼要有pre那一維度。試想,如果傳進來的時候flag已經為1,也就是說之前已經出現了49,那麼此時不管pre取什麼值,相應的dp都應該是一樣的,也就是說dp[x][0...9][1]都是相同的。再考慮到這一位之前還沒有出現49,而且前一位不是4,實際上此時不管pre取什麼值也都是相同的;唯一的例外就是之前沒有出現過49,而且前一位恰為4的情況。
換句話說,上述**的dp陣列的後兩維實際上只需要三個狀態就能夠分別。分別為到d[pos]前一位已經出現了49,用2表示;d[pos]前一位沒有出現49,但是前一位為4,用1表示;d[pos]前一位沒有出現49,而且前一位不為4,用0表示。
相應的狀態轉移方程也比較好求,見如下**:
[cpp]view plain
copy
print?
#include
#include
using
namespace std;
long
long n,dp[25][3];
int t,d[25],len;
long
long dfs(int pos,int pre,bool limit)
if(!limit)
dp[pos][pre] = res;
return res;
} long
long solve(long
long n)
return dfs(len,0,true);
} int main()
return 0;
}
hdu3555 數字dp 入門
題目大意 給乙個數字n,範圍在1 2 63 1,求1 n之間含有49的數字有多少個。思路 狀態轉移 dp i 0 代表長度為 i 並且不含有49的數字的個數 dp i 1 代表長度為 i 並且不含有49,但是最高位是9的數字的個數 dp i 2 代表長度為 i 並且含有49的數字的個數。陣列 a i...
hdu 3555數字DP 入門題
include include include include include include include include include include includeusing namespace std typedef long long ll define inf 0x3f3f3f3f ...
數字dp入門題hdu 3555
題意就是簡單的給定乙個n求1 n所有含有49的數字 數字dp入門題可以當作模板改。pos表示到pos位,pre為上一位的數字用來判斷是否可以得到49,sta表示狀態,無非就是如果該為是4的時候和不是4的時候,對下一位dp的影響。limit表示是否到了限制如213則百位是2則十位只能為0,1。這題網上...