P10236 [yLCPC2024] D. 排卡

Question 问题 P10236 [yLCPC2024] D. 排卡

题目大意:给定长度为 \(n(2 \le n \le 1000)\) 的序列 \(a\),每次可以从头或尾选一个数放到序列 \(b\)(选后删除),求\(\displaystyle \sum_{i=1}^{n-1} b_i^{b_{i+1}}\) 的最大值。(我们仅在计算 \(b_i^{b_{i+1}}\) 的时候将得分对 \(998244353\) 取模)。

Analysis 分析

首先思考贪心:(错解)

第一个从最左边或最右边拿,然后贪心第二个从最左边还是最右边使得 \(b_1^{b_2}\) 最大,一直这样贪心下去。很明显是错的。但很明显连样例的过不了,正确性显然不存在。

观察到 \(n\) 的范围较小,发现想复杂了,直接暴力区间 \(DP\) 即可。

Solution

定义 \(f_{l,r,(0,1)}\) 为区间 \([l,r]\) 最后弹掉的是最左边的(0)还是最右边的(1)。

转移方程非常好写:

\[\begin{aligned} f_{l,r,0}&=\max{\{f_{l+1,r,0}+a_l^{a_{l+1}},f_{l+1,r,1}+a_l^{a_{r}}\}}\\ f_{l,r,1}&=\max{\{f_{l,r-1,0}+a_r^{a_{l}},f_{l,r-1,1}+a_r^{a_{r-1}}\}} \end{aligned} \]

对于 \(f_{l,r,0}\) 的转移进行一个详细的讲述,\(f_{l,r,1}\) 同理。

它只能从 \([l+1,r]\) 转移而来,因为他最后踢掉的是最左边的。所以要么是 \(f_{l+1,r,0}+a_l^{a_{l+1}}\) 要么就是 \(f_{l+1,r,1}+a_l^{a_{r}}\).

Code 代码

signed main(){
	read(T);
	while(T--){
		read(n);
		for(rint i=1;i<=n;i++) read(a[i]);
		for(rint i=1;i<=n;i++) for(rint j=1;j<=n;j++) f[i,j,0]=f[i,j,1]=0;
		for(rint len=2;len<=n;len++){
			for(rint l=1;l<=(n-len+1);l++){
				int r=l+len-1;
				f_{l,r,0}=max({f_{l,r,0},f[l+1,r,0]+power(a[l],a[l+1]),f[l+1,r,1]+power(a[l],a[r])});
				f_{l,r,1}=max({f_{l,r,1},f[l,r-1,0]+power(a[r],a[l]),f[l,r-1,1]+power(a[r],a[r-1])});
			}
		}
		printf("%lld\n",max(f[1,n,0],f[1,n,1]));
	}
    return 0;
}
posted @ 2024-05-29 21:50  Mr_Azz  阅读(4)  评论(0编辑  收藏  举报