「BZOJ4576」262144

看到$c_i$的数据范围你是不是明白了什么

 (其实这种题常规写法不是区间dp吗)

但是区间dp $O(N^3)$ 显然过不去

*我们考虑一下把值域丢到状态中

设$dp_{i,j}$表示第i个数,向右合并到哪能得到j

然后就可以得到$$dp_{i,j+1}=dp_{dp_{i,j}+1,j}$$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 inline ll read() {
 5     ll x=0,f=1; char ch=getchar();
 6     for(;ch<'0'||ch>'9';ch=getchar())
 7         if(ch=='-')f=-f;
 8     for(;ch>='0'&&ch<='9';ch=getchar())
 9         x=x*10+ch-'0';
10     return x*f;
11 }
12 inline void chkmin( int &a,int b ) { if(a>b) a=b; }
13 inline void chkmax( int &a,int b ) { if(a<b) a=b; }
14 #define _ read()
15 #define ln endl
16 const int N=262150;
17 int n,a[N],dp[N][60];
18 int main() {
19     n=_;
20     for( int i=1;i<=n;i++ ) a[i]=_,dp[i][a[i]]=i;
21     for( int j=1;j<=58;j++ ) 
22         for( int i=1;i<=n;i++ ) 
23             if(!dp[i][j]); 
24             else dp[i][j+1]=dp[dp[i][j]+1][j];
25     for( int j=58;j;j-- ) 
26         for( int i=1;i<=n;i++ ) 
27             if(dp[i][j]) { cout<<j; return 0; }
28         // cout<<dp[i][2]<<" ";
29     
30 }
「BZOJ4576」262144
原文地址:https://www.cnblogs.com/gllonkxc/p/11308671.html