石子合并的圆形版和直线版差不多,关键是怎么把圆变成直线来处理。
以最小值为例:
1.先初始化mi[m][m];
2.枚举区间长度len,当区间长度为1时,相应的mi[len][i] = 0;
3.枚举起始位置i;
4.枚举插入位置,mi[j][i]代表从i开始,长度为j的最小得分。
5.将圆变成直线的方法是,当i+j大于n时,第二段开始的位置就要重新计算,
设pos为第二段开始的坐标,pos =int pos = (i+j)%n if(pos == 0) pos = n;
dp[i][j] = min(dp[i][j],dp[j][i]+dp[len-j][pos]+getsum[j][i]);
6.getsum(j,i)计算的是从i开始,长度为j的所有石子数量的和,如果i+len-1<=n
getsum(j,i) = sum[j]-sum[i-1];
如果大于
就要算出从第i堆到第n堆的石子数量,和第一队到第pos堆的石子数量
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int inf = 100000000;
const int m = 105;
int mi[m][m];
int ma[m][m];
int a[m];
int sum[m];
int mis,mas,n;
int gets