码迷,mamicode.com
首页 > Web开发 > 详细

UVALive 4731 Cellular Network

时间:2015-10-03 21:49:50      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

分析:

状态是一些有序的集合,这些集合互不相交,并集为所有区域。显然枚举集合元素是哪些是无法承受的,

写出期望的计算式,会发现一个贪心,当每个集合的大小确定了以后,概率大的优先访问是最优的。容易证明,也符合直觉。

因此先对u从大到小排序。定义状态f[i][j]表示从j开始往后分i组的最小期望。

转移是枚举划分k,则有f[i][j] = min{f[i-1][k]+(k-j)*(u[n]-u[j-1])},k>j

边界f[1][j] = (n-j+1)*(u[n]-u[j-1])

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e4+4;
int u[maxn];
int f[101][maxn];
const int INF = 0x3f3f3f3f;

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int T; cin>>T;
    while(T--){
        int n,w; scanf("%d%d",&n,&w);
        for(int i = 1; i <= n; i++) scanf("%d",u+i);
        sort(u+1,u+1+n,greater<int>());
        for(int i = 1; i <= n; i++) u[i] += u[i-1];
        for(int j = n; j > 0; j--){
            f[1][j] = (n-j+1)*(u[n]-u[j-1]);
        }
        for(int i = 2; i <= w; i++){
            for(int j = 1; j <= n; j++){
                f[i][j] = INF;
                for(int k = j+1; k <= n; k++){
                    f[i][j] = min(f[i-1][k]+(k-j)*(u[n]-u[j-1]),f[i][j]);
                }
            }
        }
        printf("%.4lf\n", f[w][1]/(double)u[n]);
    }
    return 0;
}

 

UVALive 4731 Cellular Network

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4853889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!