USACO16OPEN_248&&USACO16OPEN_262144_KEY
这道题比较水,设f[i][j]表示i~j区间合并的最大值。
#include <cstdio> #define max(a,b) a>b?a:b using namespace std; int N,x,f[250][250],ans; int main(){ scanf("%d",&N);for(int i=1;i<=N;i++)scanf("%d",&x),f[i][i]=x,ans=max(ans,x); for(int i=N-1;i>0;i--) for(int j=i+1;j<=N;j++) for(int k=i;k<j;k++) if(f[i][k]==f[k+1][j]){ f[i][j]=max(f[i][k]+1,f[i][j]); ans=max(ans,f[i][j]); } printf("%d",ans); return 0; }
但这道题目还有扩大数据范围后的做法:
仔细观察方程:
f[i][j]=max(f[i][k]+1,f[i][j]);
我们设的是i~j区间的最大值,这里有个巧妙的转化,设f[i][j]为j开始最大值达到i的右边界。
#include <cstdio> using namespace std; int N,x,f[60][262200],ans; int main(){ scanf("%d",&N);for(int i=1;i<=N;i++)scanf("%d",&x),f[x][i]=i; for(int i=2;i<=58;i++) for(int j=1;j<=N;j++){ if(!f[i][j]&&f[i-1][j])f[i][j]=f[i-1][f[i-1][j]+1]; if(f[i][j])ans=i; } printf("%d",ans); return 0; }