P3146 248 G
题面
给定一个\(1*n\)的地图,在里面玩\(2048\),每次可以让相邻的两个相同的数\(x\)合并成\(x+1\),问最大能合出多少。
\(1\leq x \leq40\)
思路
这种合并操作基本就是区间\(DP\)(狗头
设\(f[i][j]\)表示\(i\)到\(j\)合并的最大值(区间\(DP\)经典状态)
则显然转移方程就是\(f[i][j]=\max(f[i][j],f[i][k]+1),k\in[l,r),f[i][k]=f[k+1][j]\)
这样就可以水过本题了,当时其实这样是错误的
\(Hack\)数据:
Input:
8 2 1 1 2 4 2 3 4
Output:
4
如果\(f[i][k]=f[k+1][j]=0\)的话,按照上述转移方程得到的\(f[i][j]=1\),就错了
\(f[i][j]=\max(f[i][j],f[i][k]+1),k\in[l,r),f[i][k]=f[k+1][j]>0\)
code
/*
@ author:pyyyyyy/guhl37
-----思路------
-----debug-------
*/
#include<bits/stdc++.h>
using namespace std;
const int N=11155;
int n,f[N][N],ans;
int main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
cin>>n;
for(int i=1; i<=n; ++i) cin>>f[i][i],ans=max(ans,f[i][i]);
for(int len=2; len<=n; ++len)
for(int i=1; i+len-1<=n; ++i) {
int j=i+len-1;
for(int k=i; k<j; ++k)
if(f[i][k]==f[k+1][j]&&f[i][k]>0) {
f[i][j]=max(f[i][j],f[i][k]+1);
ans=max(f[i][j],ans);
}
}
cout<<ans;
return 0;
}
$$Life \quad is \quad fantastic!$$