P3146 248 G

题面

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;
}


posted @ 2020-06-15 22:04  pyyyyyy  阅读(115)  评论(0编辑  收藏  举报