數字dp題集

2022-07-15 18:33:18 字數 4081 閱讀 9978

題集見大佬部落格

入門題,檢驗剛才自己有沒有看懂

注意一些細節。

的確挺套路的

#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

const

int maxn = 15

;int a[maxn], dp[maxn][maxn][maxn], len; //

dp陣列記錄除了lead和limit以外其他的東西

int dfs(int pos, int pre, int lead, int sum, int

limit)

return (!limit && !lead) ? dp[pos][pre][sum] = res : res; //

記憶化的時候記得limit和lead

}int part(int

x)int

main()

return0;

}

繼續套路

#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

const

int maxn = 15

;int

a[maxn], dp[maxn][maxn][maxn], len;

int dfs(int pos, int pre, int ans, int lead, int

limit)

return (!limit && !lead) ? dp[pos][pre][ans] =res : res;

}int part(int

x)int

main()

第一次這麼輕鬆做出紫題

一樣套模板,爽啊

#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

typedef

long

long

ll;const

int maxn = 20

;const

int maxm = 1e6 + 10

;ll dp[maxn][maxn];

inta[maxn], len;

ll dfs(

int pos, int ans, int lead, int limit, int

key)

return (!lead && !limit) ? dp[pos][ans] =res : res;

}ll part(ll x,

inti)

inline ll work(ll a, ll b,

inti)

intmain()

注意數字很大,要用字串儲存

然後就沒啥了,又獨立做出紫題

#include#define add(a, b) a = (a + b) % mod

#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

const

int maxn = 12

;const

int maxm = 1e3 + 10

;const

int mod = 1e9 + 7

;int dp[maxm][maxn][maxn][2

];int

a[maxm], len;

char

s1[maxm], s2[maxm];

int dfs(int pos, int pre, int ppre, int ans, int lead, int

limit)

return (!lead && !limit) ? dp[pos][pre][ppre][ans] =res : res;

}int part(char*s)

int judge(char*s)

intmain()

一開始想的時候當前的數肯定是不能記到答案裡的

當然如果知道模數,一直取模就可以限制範圍,就很好了

但問題是我們並不知道模數,這就比較尷尬了

就一直卡在這

然而正解非常暴力,但卻是對的。

既然不知道模數,那就列舉模數

最後判斷一下數字和是不是當前模數且能否整除就好了。

我為什麼沒想到呢?

注意數字dp要開long long

#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

typedef

long

long

ll;const

int maxn = 20

;ll dp[maxn][maxn*10][maxn*10

];int

a[maxn], len, mod;

ll dfs(

int pos, int num, int state, int lead, int

limit)

return (!lead && !limit) ? dp[pos][num][state] =res : res;

}ll part(ll x)

return

res;

}int

main()

用二進位制統計就好了

不過很奇怪的是一開始我陣列開的大小是50

因為用程式輸出1e15最多的位數是47

但是交上去會wa乙個點

改成51就過了

以後只要空間剩餘多,就多開一些吧,程式中有些神奇的地方可能會比理論上最大值超出一些

#include#define mul(a, b) a = (a * b) % mod

#define rep(i, a, b) for(register int i = (a); i < (b); i++)

#define _for(i, a, b) for(register int i = (a); i <= (b); i++)

using

namespace

std;

typedef

long

long

ll;const

int maxn = 51

;const

int mod = 10000007

;ll dp[maxn][maxn];

inta[maxn], len;

ll dfs(

int pos, int ans, int lead, int

limit)

return (!limit && !lead) ? dp[pos][ans] =res : res;

}ll part(ll x)

intmain()

總結感覺都是套路,掌握套路就好了

相信自己已經掌握了數字dp

數字dp 板子題

題目傳送 存乙個狀態就可以了,用來判斷前一位是不是6的情況 具體看 注釋 ac include inline long long read while c 0 c 9 return x s using namespace std define newnode treenode malloc size...

換根dp題集

題目鏈結 題意 給你一棵樹,按順序輸出以每個頂點為根節點,到任意點的邊權和最大,輸出這個最大值。思路 換根dp,兩遍dfs,第乙個dfs求出以這個點為根節點,子樹的最大邊權值,儲存在d陣列中。第二個dfs1,首先算出以u節點為根節點的dp值,儲存在ans陣列裡,然後求出u節點的兒子的字首dp值儲存在...

數字dp 計數問題 模板題 數字dp

數字dp目前見的比較少,最為經典的莫過於不要62,或許以前都是暴力求解。例如求解1 n中,數字x出現的次數這類題,暴力列舉每個數的時間複雜度為 o n o n o n 再列舉每一位的時間複雜度為 log 10nlog n log10n 數字一大妥妥超時。值得一提的是,2020 的藍橋杯,第一道簽到題...