HDOJ 4352 數字dp 題解

2022-05-09 20:13:23 字數 1152 閱讀 2846

數字dp好套路啊,感覺只要會這個套路已經做出題目大半了

題目前面全是廢話,只要看題目描述的倒數第二行就行了

大意是每次給定 \(l,r,k\),求區間 \([l,r]\) 內滿足要求的數的個數,要求是這個數字的十進位制表示的最長上公升子串行等於 k,(資料組數 \(\le 10000,0)

比如 \(1123\) 的 lis 等於 \(3\),\(10123\) 的 lis 等於 \(4\)

首先講一下數字dp的套路,就是記憶化搜尋(因為很多題目都是多次給出 \(l,r\),記憶化搜尋方便很多),然後從最高位往低位搜尋,搜尋時要維護 \(4\) 個量,乙個是當前搜尋到的位數 \(pos\),乙個是狀態(狀態可以用多個數表示),乙個是 \(lim\),表示是否被限制,最後乙個是 \(lz\),表示當前位的前一位是不是前導零(口胡的,聽不懂大致看看**就知道了)

另外這題的狀態用了一下狀壓,\(a\) 的第 \(b_1,b_2,...,b_k\) 位是 \(1\) 代表當前最優秀的上公升序列是 \([b_1,b_2,...,b_k]\),push函式返回把 \(x\) 加入 \(a\) 後的狀態

#include using namespace std;

#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)

#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)

#define mst(a,x) memset(a,x,sizeof(a))

typedef long long ll; const int inf=~0u>>2; const ll inf=~0ull>>2; ll read()

ll dp[20][1<<10][11],bit[20],k;

int push(int a,int x)

a^=(1

}ll dfs(int pos,int a,bool lim,bool lz)

if(!lim)x=ans; //不限制的時候才做儲存

return ans;

}ll solve(ll n)

return dfs(len-1,0,1,1);

}signed main()

return 0;

}

hdu4352 數字dp 狀態壓縮

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

HDU4352 lis 狀壓 數字dp

題幹很智障,意思就是問從l到r裡lis為k的數有幾個 首先從0到9一共十個數,那麼最長不能超過10 dp陣列開乙個狀態,位數,k這樣的三維就夠 狀態是狀態壓縮的狀態 你可以用狀態壓縮來表達lis的陣列 有點取巧了,我看別人的題解都是兩維,lis部分用的nlgn方法 我第一次看見tle以後直接開了第三...

HDU 4352(數字dp 狀態壓縮 LIS)

求區間範圍內最長上公升子串行數字k的數字有多少個 首先由數字dp引入思路,dp轉移方程為 dfs pos,status.累加dfs pos 1,stautselse 可備忘錄記錄的dp陣列為 dp pos status k 之所以要備忘錄k,是為了滿足不同k的訪問 status記錄的是開頭數字到po...