U45490 還沒想好名字的題Ⅱ
阿新 • • 發佈:2018-11-11
這一題的環狀板
Solution
暴力斷環為鏈, 列舉起點跑 \(n\) 遍 \(DP\), 取最小值即可
Code
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> #include<climits> #include<cmath> #define LL long long #define REP(i, x, y) for(int i = (x);i <= (y);i++) using namespace std; int RD(){ int out = 0,flag = 1;char c = getchar(); while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();} while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();} return flag * out; } const int maxn = 419; int num, m; double dp[maxn][maxn], a[maxn], sum[maxn], ave; double DP(int l, int r){ REP(i, 0, num)REP(j, 0, m)dp[i][j] = 1e19; dp[0][0] = 0; REP(i, l, r) REP(j, 1, i) REP(k, l - 1, i - 1) dp[i][j] = min(dp[i][j], dp[k][j - 1] + ((sum[i] - sum[k] - ave) * (sum[i] - sum[k] - ave))); return dp[r][m]; } int main(){ num = RD(), m = RD(); REP(i, 1, num)a[i] = a[i + num] = RD();//斷環為鏈 REP(i, 1, num * 2)sum[i] = sum[i - 1] + a[i]; ave = sum[num] / (m * 1.0); double ans = 1e9; REP(i, 1, num)ans = min(ans, DP(i, i + num)); printf("%.2lf\n", sqrt(ans / (double)m)); return 0; }