bzoj1575 [Usaco2009 Jan]气象牛Baric

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1575

【题解】

动态规划,令f[i,j]表示前i个选了j个,且第i个必选的最小值。

转移就枚举上一个,再暴力算贡献即可。

复杂度O(n^4)

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 100 + 10;
const int mod = 1e9+7, inf = 1e9;

# define RG register
# define ST static
# define ABS(x) ((x) >= 0 ? (x) : -(x))

int n, E, s[M], f[M][M];


int main() {
    cin >> n >> E;
    for (int i=1; i<=n; ++i) scanf("%d", s+i);
//    sort(s+1, s+n+1);
    
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=n; ++j)
            f[i][j] = inf;
    
    for (int i=1; i<=n; ++i) {
        // f[i,1]
        f[i][1] = 0;
        for (int j=1; j<=i-1; ++j)
            f[i][1] = f[i][1] + 2 * ABS(s[i]-s[j]);
        for (int j=i+1; j<=n; ++j)
            f[i][1] = f[i][1] + 2 * ABS(s[i]-s[j]);
    }
    
    for (int i=1; i<=n; ++i)
        for (int j=2; j<=i; ++j) {
            f[i][j] = inf;
            for (int k=j-1; k<i; ++k) {
                int cur = f[k][j-1];
                if(cur == inf) continue;
                for (int l=k+1; l<=n; ++l)
                    cur = cur - 2 * ABS(s[l] - s[k]);
                for (int l=k+1; l<=i-1; ++l) 
                    cur = cur + ABS(2*s[l] - s[i] - s[k]);
                for (int l=i+1; l<=n; ++l)
                    cur = cur + 2 * ABS(s[l] - s[i]);
                f[i][j] = min(f[i][j], cur);
            }
        }
        
    
    for (int j=1; j<=n; ++j) {
        int ans = inf;
        for (int i=j; i<=n; ++i) 
            ans = min(ans, f[i][j]);
//        cout << j << ' ' << ans << endl;
        if(ans <= E) {
            printf("%d %d\n", j, ans);
            return 0;
        }
    }

    return 0;
}
View Code

 

posted @ 2017-06-09 16:09  Galaxies  阅读(163)  评论(0编辑  收藏  举报