數字dp從會打模板到不會打模板

2022-04-14 04:12:03 字數 3078 閱讀 3994

打了幾個數字$dp$,發現自己除了會打模板之外沒有任何長進,遇到非模板題依然什麼都不會

那麼接下來這篇文章將介紹如何打模板(滑稽)

假設我們要處理$l----r$

採用記憶化搜尋的方式,列舉$<=r$每一種情況,列舉每一位,然後再列舉$<=l-1$每一種情況,然後兩個值相減即可

我們可以比較輕鬆打出乙個模板

ll dfs(ll x,ll pre,ll lead,ll limit)

if(!limit&&!lead) f[x][pre]=ans;

return

ans;

}

解釋一下$limit$是什麼

假設有乙個數

$1\   2\  3\  4\  5\  6$

$1\   2\  3\  ?\  ?\  ?$

我們列舉到第四位時最多列舉到$4$,

$1\   2\  3\  4\  5\  6$

$1\   2\  2\  ?\  ?\  ?$

這時我們列舉到第四位最多列舉到$9$

$limit$就是判斷這個的

那麼為什麼要在$!limit$下才記憶化呢?

如果在所有情況下我們都記錄f,那麼假如之前列舉到$9$時你記錄了乙個答案,然後當前位有$limit$限制根本列舉不到$9$,你仍然用了這個f會出現錯誤

當然你這樣記憶化也可以這樣避免衝突

ll dfs(ll x,ll limit,ll tmp,ll d)

解釋一下$lead$

處理前導0用的,

有的時候

$0\   0\  0\  4\  5\  6$

也被認為是合法的,這時處理可能會出現問題,$lead$特判特殊處理

那麼我們看幾道模板題

windy 定義了一種 windy 數:不含前導零且相鄰兩個數字之差至少為2的正整數被稱為 windy 數。

windy 想知道,在l和r 之間,包括l 和 r,總共有多少個 windy 數?

非常簡單對不對

套模板

#includeusing

namespace

std;

#define ll long long

#define a 50ll f[a][a],maxn[a];

ll pos=0

,a,b;

ll dfs(ll x,ll pre,ll lead,ll limit)

if(!limit&&!lead) f[x][pre]=ans;

return

ans;

}ll solve(ll x)

ll ans=dfs(1,-2,1,1

);

return

ans;

}int

main()

$l---r$間數字上不含$4$且沒有$62$相連的數個數

套模板

#includeusing

namespace

std;

#define ll long long

#define a 50ll f[a][a],maxn[a];

ll pos=0

,a,b;

ll dfs(ll x,ll pre,ll limit)

//printf("ans=%lld\n",ans);

if(!limit) f[x][pre]=ans;

return

ans;

}ll solve(ll x)

ll ans=dfs(pos,0,1

);

return

ans;

}int

main()

printf(

"%lld\n

",solve(a)-solve(b-1

)); }

}

至少$3$個相鄰的相同的數,$8$ $4$不能同時出現

套模板,注意下特判,不然會70到自閉

#includeusing

namespace

std;

#define ll long long

#define a 30ll f[a][a][a][

2][2][2

],pos[a];

ll tot=0

,a,b;

ll dfs(ll x,ll prer,ll pre,ll limit,ll _4,ll _8,ll ok)

if(!limit)

f[x][prer][pre][_4][_8][ok]=ans;

return

ans;

}ll solve(ll x)

ll ans=dfs(1,0,0,1,0,0,0

);

return

ans;

}int

main()

設 sum(i) 表示 i 的二進位制表示中 1 的個數。給出乙個正整數 n ,花神要問你派(sum(i)),也就是 sum(1)—sum(n) 的乘積。

套模板,等等,我要套什麼,

這個題不算很板,值得思考思考。

數字dp計算出所有二進位制下sum個數,然後快速冪處理一下,

#includeusing

namespace

std;

#define a 53

#define mod 10000007

#define ll long longll n,tot=0,sum=0

;ll f[a][

2][a][a],ans[a],pos[a];

ll dfs(ll cur,ll up,ll tmp,ll d)

ll meng(ll a,ll b)

ll solve(ll x)

for(ll i=1;i<=tot;i++)

for(ll i=1;i<=tot;i++)

return

sum;

}int

main()

剩下一些題都不算很板

數數淘金

方伯伯商場之旅

題解慢慢補充八

那麼你現在會模板了嗎?

數字dp 模板

dp pos,狀態變數.限制布林 if limit dp 狀態 a 已經求出對應狀態值下的結果了 記錄下來 return a 所以 數字dp其實就是一種求解有關於l到r有多少個符合條件的數目類似的統計問題的解題思路 一遍遍數字列舉太慢 不如我們根據條件列舉數字 數字dp本質上是記憶化搜尋 我們需要在...

數字DP模板

數字dp問題,大多是統計數量,通常用按位處理的方法解決。具體為 詢問 l,r l,r l,r 中滿足某一條件的數。利用字首和的思想,我們可以把問題簡化,即轉化為詢問 1,r 1,r 1,r 和 1,l 1 1,l 1 1,l 1 實現時,常常使用記憶化搜尋,由於有很多限制條件,所以常常增加幾維狀態,...

數字dp模板

typedef long long ll int a 20 ll dp 20 state 不同題目狀態不同 ll dfs int pos,state變數 bool lead 前導零 bool limit 數字上界變數 不是每個題都要判斷前導零 計算完,記錄狀態 if limit lead dp po...