原題鏈結
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 對於每組...