數字dp 學習指南

2021-06-22 21:59:43 字數 3458 閱讀 5515

在資訊學競賽中,有一類難度不大但異常麻煩的問題——數字計數問題,這類問題的主

要特點是詢問的答案和一段連續的數的各個數字相關,並且需要對時間效率有一定要求。由

於解決這類問題往往意味著巨大的**量,而眾多的特殊情況又意味著出現錯誤的巨大可能

性,因此很少有人願意解決此類問題,但只要掌握好的方法,解決這類問題也並非想象中的

那樣困難。

對於乙個數,若其首位已經比詢問上界小,則剩餘位沒有任何限制。此時如果能直接處理這一情況,則問題距離解決又會邁出一大步。 

例如,在十進位制下,計算[10000,54321]內的數字和,我們可以將其分解為:

[10000,19999],[20000,29999],[30000,39999],[40000,49999],[50000,54321]。

前四個區間如果可以直接解決,則只需處理最後乙個區間,進一步將最後乙個區間劃分

為:[50000,50999],[51000,51999],[52000,52999],[53000,53999],[54000,54321]。同理將最後一

個區間劃分下去,最後可以得到以下區間劃分:

[10000,19999],[20000,29999],[30000,39999],[40000,49999],

[50000,50999],[51000,51999],[52000,52999],[53000,53999],

[54000,54099],[54100,54199],[54200,54299],

[54300,54309],[54310,54319],

[54320,54321]

該模板出處不詳,但是此模板大大降低了數字dp類問題的難度。

typedef long long ll;

const int maxn=22;

int dig[maxn];

ll f[maxn]/* [todo] */;

ll dfs(int pos,/* todo */,int limit)

if (!limit) f[pos]/* [todo] */=res;

return res;

}ll solve(ll n)

return dfs(len-1,/* todo */,1);

}

求給定區間中不含有62和4的數的個數。

ll dfs(int pos,int pre,int fg,int limit)

if (!limit) f[pos][pre][fg]=res;

return res;

}

求給定區間的含有49的數的個數。

ll dfs(int pos,int pre,int istrue,int limit)

if (!limit) f[pos][pre][istrue]=ret;

return ret;

}

求給定區間範圍內的,求相鄰數字之差絕對值不小於2的數的個數。

ll dfs(int pos,int pre,int fg,int limit)

if (!limit) f[pos][pre][fg]=ret;

return ret;

}

平衡數。數n以數n中的某個位為支點,每個位上的數權值為(數字xi*(posi - 支點的posi)),如果數n裡有乙個支點使得所有數權值之和為0那麼她就是平衡數。比如4139,以3為支點,左邊 = 4 * (4 - 2) + 1 * (3 - 2) = 9,右邊 = 9 * (1 - 2) = -9,左邊加右邊為0,所以4139是平衡數。現在給出乙個區間[l,r],問區間內平衡數有多少個?

ll dfs(int pos,int o,int pre,int limit)

if (!limit) f[pos][o][pre]=res;

return res;

}ll solve(ll n)

ll ans=0;

for (int i=0;i

如果乙個數能夠被其每個數字的數都整除,那麼這個數就叫做美麗數。

int check(int bit,int mod)

}return 1;

}ll dfs(int pos,int bit,int mod,int limit)

if (!limit) f[pos][bit][mod]=ret;

return ret;

}

求小於n是13的倍數且含有'13'的數的個數。

ll dfs(int pos,int pre,int fg,int md,int limit)

if (!limit) f[pos][pre][fg][md]=res;

return res;

}

求[l,r]內最長遞增子串行是k的數的個數;

ll f[maxn][1<<10][11];

int k;

int dig[maxn];

int getlis(int bit)

inline ll sec(piii a)

inline ll thd(piii a)

inline piii makezeropiii()

inline piii makeonepiii()

ll power[maxn];

piii f[maxn][11][8];

bool v[maxn][11][8];

int dig[maxn];

piii gao(piii a, piii b,int i,int pos)

piii dfs(int pos,int pre,int sev,int limit)

if (!limit&&v[pos][pre][sev]) return f[pos][pre][sev];

piii res=makezeropiii();

int last=limit?dig[pos]:9;

for (int i=0;i<=last;i++)

if (!limit)

return res;

}ll solve(ll n)

piii ans = dfs(len-1,0,0,1);

return thd(ans);

}int main()

{ memset(v,0,sizeof(v));

memset(power,0,sizeof(power));

power[0]=1;

for (int i=1;i>t;

while (t--){

ll a,b;

cin>>a>>b;

cout<<(solve(b)-solve(a-1)+mod)%mod<

Linux 學習指南

第乙個話題,嵌入式學習的路徑有哪些.這是乙個初學者常問的問題,也是初學者問嵌入式該如何入門的根源.我感覺有兩個方面,偏硬和偏軟.我不認為嵌入式開發軟體佔絕對比重,相反,軟硬體都懂,才是嵌入式高手所應該追求的,也是高手的必由之路.硬體道路 第一步 pcb設計,一般為開發板的電路裁減和擴充,由開發板原理...

Perl學習指南

首先,請考慮如下問題 如果你學過其他語言,那就可以從學習 perl 的語法開始 perl語言入門 或者是從 perl 的自帶文件。當你對 perl 的語法了解後,嘗試書中的例子,試著寫一些簡單的程式。很快你就會發現 perl 和你以前學過的語言類似。如果你是乙個有經驗的程式設計師,你可能直接會從讀程...

SAP HANA 學習指南

sap hana 學習指南 第一部分 sap hana 概覽 第二部分 sap hana資料庫體系結構 2.1 體系結構概覽 2.2 記憶體結構 2.3 sap hana 多版本併發控制 sap hana mvcc 2.4 列儲存 column store 2.5 行儲存 row store 2.6...