數字dp HDU 4352 LIS狀態壓縮

2021-09-25 01:53:53 字數 1480 閱讀 1116

題目大意:題意:介紹了電子科大的乙個傳奇學姐,最後幾句話才是題意,這題意思就是給你乙個ll範圍內的區間[l, r],問你在這個區間內最長遞增子串行長度恰為k的數有多少個。

在dp過程中,我們要維護lis。而且數字只有0-9,如果你知道怎麼在o(n * logn)的時間複雜度維護lis,那麼就好辦了。但是這個方法用維護乙個棧,每次替換棧中第乙個大於當前值的數。但是我們怎麼把乙個大小最大為10的棧表示為狀態。就是狀態壓縮:用乙個int來表示棧0000000000。這表示乙個空棧。

舉例來說:如果sta按照數字13425來更新。

首先遇到1,變成 0100000000 (或者0000000010,其實這是完全一樣的,只要保證不同狀態的sta不一樣就行了)

然後遇到3,很明顯,之前沒有比3更大的數字,然後變成0101000000

遇到4,sta變成0101100000

在這裡打斷一下,不能看出,sta中1的個數,就是lis的長度。

然後遇到2,這時大於等於2的有乙個3.於是把3的二進位制1交給2,sta變成0110100000 實現替換。遇到4,sta變成0101100000

所以:sta中1的個數,就是lis的長度。

當然要判斷前導0,例如:1 10 2,如果沒有判斷前導0,那麼pos=1時,當前數為0, 棧變1000000000, 再列舉pos=0時,那麼1 2 3 4 5 6 7 8 9都滿足條件了。所以必須考慮前導0的影響。

#include

#define ll long long

using

namespace std;

ll a[20]

;ll dp[20]

[1024][

15];ll size

(ll x)

//二進位制0的個數

return ans;

}ll lis

(ll st, ll k)

//維護lis

}return st|(1

<

ll dfs

(ll pos, ll st, ll lead, ll mt, ll k)

else}if

(!lead&&

!mt&&dp[pos]

[st]

[k]!=-1

) ll len=mt?a[pos]:9

; ll ans=0;

for(ll i=

0;i<=len;i++)if

(!mt&&

!lead)

return ans;

}ll slove

(ll x, ll k)

return

dfs(pos-1,

0,1,

1, k);}

intmain()

return0;

}

HDOJ 4352 數字dp 題解

數字dp好套路啊,感覺只要會這個套路已經做出題目大半了 題目前面全是廢話,只要看題目描述的倒數第二行就行了 大意是每次給定 l,r,k 求區間 l,r 內滿足要求的數的個數,要求是這個數字的十進位制表示的最長上公升子串行等於 k,資料組數 le 10000,0 比如 1123 的 lis 等於 3 ...

hdu4352 數字dp 狀態壓縮

題意 給出l和r找出在 l,r 中滿足最長遞增子串行長度等於k的個數。題解 狀壓想不到,看了kuangbin的才明白,1 10狀壓存數出現了沒有。利用了nlogn遞增字序列演算法的思想。include include include include includeusing namespace st...

數字DP HDU2089 不要62

problem description 杭州人稱那些傻乎乎粘嗒嗒的人為62 音 laoer 杭州交通管理局經常會擴充一些的士車牌照,新近出來乙個好訊息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大眾。不吉利的數字為所有含有4或62的號碼。例如 ...