U45490 还没想好名字的题Ⅱ

这一题的环状板

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;
	}
posted @ 2018-10-17 21:50  Tony_Double_Sky  阅读(96)  评论(0编辑  收藏  举报