P1043 數字遊戲(區間dp)
思路:區間題目,首先將環形用兩倍數組存,然後初始化區間長度爲1的答案,然後用區間即可。
時間複雜度:
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;
}