[TK] 矩阵取数游戏<简单版> hzoi-tg-906-2

本题是一个坐标DP问题

状态转移

首先我们注意到,一个状态只能由两种前置状态得到:取左边的数和取右边的数,因此我们以状态为阶段定义如下:

f[a][b][c] 为状态转移数组,其中 a 为已取走的数目,区间 [b,c] 为未取走的所有数组成的区间(能够发现,未取走的所有数组成的区间一定是连贯的,所以我们这样定义),数组表示该状态下的最大得分.

根据上述推论,可以得出状态转移方程:

f[k][i][j]=max{f[k1][i][j+1]+cost[j+1]f[k1][i1][j]+cost[i1]

其中上面的转移式是取右边的数,下面的转移式是取左边的数. cost[i] 表示拿走这个数的得分.

细节处理

1.结果输出

我们可以发现,在拿走 n1 个物品后,区间内一定会剩余一个,也就是此时状态转移方程为 f[n1][i][i] 的形式.
我们可以直接找出所有 f[n1][i][i]+cost[i] 中的最大值作为答案.

2.计算 cost[i]

不难发现,本题中 cost[i]=s[i]×2k. 有人会想到快速幂,但是题目最大只有 k=30,所以还是打表更有性价比.我们直接在开头预处理全部数值存进数组就行.

代码实现

假如你是来抄代码的 建议你动点脑子理解一下上面的东西 这里只给出伪代码
	for(int i=1;i<=n;++i){        //预处理
		base[i]=base[i-1]*2;
	}
	for(int i=1;i<=n;++i){
		cin>>y[i];
	}
	for(k:1~n-1){
		for(i:1~n){
			for(j:1~n){
				f[k][i][j]=max(f[k-1][i][j+1]+y[j+1]*base[k],f[k-1][i-1][j]+y[i-1]*base[k]);
			}
		}
	}
	for(i:1~n){
		ans=max(f[n-1][i][i]+y[i]*base[n],ans);
	}
}
//别忘了开long long
posted @   HaneDaniko  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示