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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章