完美消除(數字dp,單調棧)

2021-10-14 07:52:17 字數 1187 閱讀 1714

原題鏈結

1.對於乙個數的花費,可以把數從高位到地位列舉,利用單調棧。比如當前位為x,把棧裡比x大的全部彈出。然後如果棧裡還有x,則不把x放入,運算元不變。若棧裡沒有x,可以把x放進去,運算元+1。

比如323 。3進棧 op=1。2來了,把3彈出,2放進去 op=2。3來了,把3放入棧中,op=3

比如232 。2進棧 op=1。3來了,3進棧,op=2 。2來了,把3彈出,2已經在裡面了,不用放進去,op=2。

2.d p[

i][k

][st

]dp[i][k][st]

dp[i][

k][s

t]表示當前在第pos位,操作次數為k,棧的狀態st

3.注意棧內一開始要把0放進去。因為0是不用花費的,當列舉到0時,棧裡始終有0,不會累加操作次數

#include

using

namespace std;

typedef

long

long ll;

const

int n=20;

ll dp[n]

[n][

1<<10]

,l,r,k,a[n]

;ll dfs

(int pos,ll op,ll st,

int limit)

//op表示操作次數,st表示單調遞增棧內元素狀態,第i位為1則有i這個數

if(now>>i&

1) res+

=dfs

(pos-

1,op,now,i==up&&limit)

;//棧內有i這個數

else

if(op=dfs

(pos-

1,op+

1,now|(1

<,i==up&&limit)

;//沒有這個數,運算元+1,把這個數放進棧裡 }if

(!limit)dp[pos]

[op]

[st]

=res;

return res;

}ll gan

(ll n)

return

dfs(cnt,0,

1,1)

;//棧內初始要放0,因為0是不花費次數的

}int

main()

51nod 1623 完美消除(數字DP)

首先考慮一下給乙個數如何求它需要多少次操作。顯然用乙個單調棧就可以完成 塞入棧中,將比它大的所有數都彈出,如果棧中沒有當前數,答案 1。因為數的範圍只有0 9,所以我們可以用乙個二進位制數來模擬這個棧,並塞到dp的狀態裡。設 dp i j k 表示前i位數,已經進行了j次操作,棧的狀態為k的方案數。...

ACdream 1064 完美數(數字dp)

題意 在 l r 的正整數區間內,要麼包含3 要麼包含 8 的不同的整數有多少個?題解 數字dp。設 dp i 0 表示既沒有3也沒有8的,dp i 1 表示有3但是沒有8的,dp i 2 表示有8但是沒有3的。this code is made by lzyrapx problem 1064 ve...

ACdream 1064 完美數 數字DP

8是中國人很喜歡的乙個數字,但是如果有3的存在就變成了38,就不是很好了。你能告訴我,在 l,r 的正整數區間內,要麼包含3 要麼包含 8 的不同的整數有多少個麼?input 第一行乙個整數t t 10000 代表資料的組數 對於每組資料給兩個整數 l,r 1 l r 1e9 output 對於每組...