P1043 数字游戏(区间dp)

P1043 数字游戏(区间dp)

传送门

思路:区间dpdp题目,首先将环形用两倍数组存,然后初始化区间长度为1的答案,然后用区间dpdp即可。

时间复杂度:O(mn3)O(mn^3)

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=105,inf=0x3f3f3f3f;
int a[N][N][10],b[N][N][10],n,m,f[N];//数组a,b分别保存最大值,最小值
int fun(int i,int j){
	int x=f[j]-f[i];
	return ((x%10)+10)%10;//负数取模. 
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&f[i]),f[i+n]=f[i];//将环变成数组储存. 
	for(int i=1;i<=2*n;i++) f[i]+=f[i-1];
	for(int l=1;l<=2*n;l++)
		for(int r=l;r<=2*n;r++) a[l][r][1]=b[l][r][1]=fun(l-1,r);//初始化 
	for(int k=2;k<=m;k++)
		for(int i=1;i<=2*n;i++)
			for(int j=i+k-1;j<=2*n;j++)	b[i][j][k]=inf;//最小值初始化最大. 
	for(int k=2;k<=m;k++)//区间dp板子 
		for(int i=1;i<=2*n;i++)
			for(int j=i+k-1;j<=2*n;j++)
				for(int p=i+k-2;p<j;p++){//分割点. 
					a[i][j][k]=max(a[i][j][k],a[i][p][k-1]*fun(p,j));
					b[i][j][k]=min(b[i][j][k],b[i][p][k-1]*fun(p,j));
				}
	int mx=0,mn=inf;
	for(int i=1;i<=n;i++)//求最值. 
		mx=max(mx,a[i][i+n-1][m]),mn=min(mn,b[i][i+n-1][m]);
	printf("%d\n%d",mn,mx);
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章