hdu 3555 數字dp入門

2021-08-01 15:43:40 字數 1475 閱讀 3300

題意:給定乙個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。這題網上...