打了幾個數字$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 數?
非常簡單對不對
套模板
#includeusingnamespace
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$相連的數個數
套模板
#includeusingnamespace
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到自閉
#includeusingnamespace
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個數,然後快速冪處理一下,
#includeusingnamespace
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...