这个题WA了n次。。。
用dp[x][y][z]表示以x为开头,长度为y,并且分成z分时的最大,或者最小结果。则状态转移方程为dp[x][y][z]=max(dp[x+i][y-i][z-1]*sum(x->x+i-1)%10)。
我的AC代码
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXI 0x07777777
int n,m;
int a[60];
int dp[60][60][15];
void init(){
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> a[i];
}
memset(dp, -1, sizeof(dp));
}
int smaller (int x, int y) {
return (x < y ? x : y);
}
int bigger (int x, int y){
return (x > y ? x : y);
}
int digui (int x, int y, int z){ // 此处是求最大值
if(dp[x][y][z]!=-1) return dp[x][y][z];
if (z==1) {
int temp = 0;
for(int i = 1; i <= y; i++) temp += a[(x+i-1)%n];
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
dp[x][y][z] = temp;
return temp;
}
int result = 0;
for(int i = 1; i <= y-(z-1); i++){
int temp = 0;
for(int j = x; j <= x+i-1; j++) temp += a[j%n];
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
result = (result < temp*digui((x+i)%n,y-i,z-1) ? temp*digui((x+i)%n,y-i,z-1) : result);
}
dp[x][y][z] = result;
return result;
}
int digui1 (int x, int y, int z){ //此处是求最小值
if(dp[x][y][z]!=-1) return dp[x][y][z];
if (z==1) {
int temp = 0;
for(int i = 1; i <= y; i++) temp += a[(x+i-1)%n];
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
dp[x][y][z] = temp;
return temp;
}
int result = MAXI;
for(int i = 1; i <= y-(z-1); i++){
int temp = 0;
for(int j = x; j <= x+i-1; j++) temp += a[j%n];
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
result = (result > temp*digui1((x+i)%n,y-i,z-1) ? temp*digui1((x+i)%n,y-i,z-1) : result);
}
dp[x][y][z] = result;
return result;
}
int main(int argc, const char * argv[])
{
init();
int maxresult = 0;
int minresult = MAXI;
if(m==1){ // m可以等于1,一开始没考虑,一直运行时错误。。。
int temp = 0;
for(int i = 0; i < n; i++) temp += a[i];
temp = (temp %10 < 0 ? temp%10+10 : temp%10);
cout << temp << endl;
cout << temp << endl;
return 0;
}
for(int i = 0; i < n; i++){
for(int j = 1; j <= n-(m-1); j++){
int temp = 0;
for(int u = i; u < i+j; u++){
int tempu = u%n;
temp += a[tempu];
}
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
int t = temp*digui((i+j)%n,n-j,m-1);
maxresult = (maxresult < t ? t : maxresult);
}
}
memset(dp, -1, sizeof(dp));
for(int i = 0; i < n; i++){
for(int j = 1; j <= n-(m-1); j++){
int temp = 0;
for(int u = i; u < i+j; u++){
int tempu = u%n;
temp += a[tempu];
}
temp = (temp%10 < 0 ? temp%10+10 : temp%10);
int t = temp*digui1((i+j)%n,n-j,m-1);
minresult = (minresult > t ? t : minresult);
}
}
cout << minresult << endl;
cout << maxresult << endl;
}