zoukankan      html  css  js  c++  java
  • hdu 4412 利用单调性的动态规划

    思路:

    这题和1227的求法一样,只不过1227是小数据,暴力下,就能进行预处理。

    这题的预处理区间期望cost[i][j]需要利用单调性。

    即假使以pos位置为安排的点,那么这个区间在其左边的概率为l,右边的概率为r,总期望为sum。如果将安排点从pos放到pos-1

    该区间增加的期望为r*(p[pos].x-p[pos-1].x)

    减少的期望为l*(p[pos].x-p[pos-1].x)

    如果减少的超过增加的,那么pos-1就比pos好。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #define Maxn 1010
    using namespace std;
    double dp[Maxn][60],cost[Maxn][Maxn];
    struct Point{
        int x;
        double p;
    }p[Maxn];
    map<int ,double> vi;
    int main()
    {
        int n,m,i,j,l,x,k;
        double cc;
        while(scanf("%d%d",&n,&m)!=EOF,n||m)
        {
            memset(dp,0,sizeof(dp));
            memset(p,0,sizeof(p));
            memset(cost,0,sizeof(cost));
            vi.clear();
            int mx=0;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&l);
                while(l--)
                {
                    scanf("%d%lf",&x,&cc);
                    vi[x]+=cc;
                }
            }
            int cnt=0;
            map<int ,double> ::iterator it;
            for(it=vi.begin();it!=vi.end();it++)
                p[++cnt].x=it->first,p[cnt].p=it->second;
            double l,r,sum;
            int pos;
            double t;
            for(i=cnt;i>1;i--)
            {
                l=r=sum=0;
                r=p[i].p;
                pos=i;
                for(j=i-1;j>=1;j--)
                {
                    l+=p[j].p;
                    sum+=p[j].p*(p[pos].x-p[j].x);
                    while(pos>1&&(t=(r-l)*(p[pos].x-p[pos-1].x))<0)
                    {
                        sum+=t;
                        pos--;
                        l-=p[pos].p;
                        r+=p[pos].p;
                    }
                    cost[j][i]=sum;
                }
            }
            for(i=1;i<=cnt;i++)
                dp[i][1]=cost[1][i];
            for(i=1;i<=m;i++)
                dp[1][i]=0;
            for(k=2;k<=m;k++)
            {
                for(i=1;i<=cnt;i++)
                {
                    if(i<=k) {dp[i][k]=0;continue;}
                    dp[i][k]=1e20;
                    for(j=i-1;j>=1;j--)
                        dp[i][k]=min(dp[i][k],dp[j][k-1]+cost[j+1][i]);
                }
            }
            printf("%.2lf
    ",dp[cnt][m]);
        }
        return 0;
    }
  • 相关阅读:
    2017面向对象程序设计寒假作业2!
    寒假学习计划
    2017面向对象程序设计寒假作业1!
    bzoj3583 杰杰的女性朋友
    poj1185 [NOI2001炮兵阵地]
    bzoj1009 [HNOI2008]GT考试
    EXKMP
    bzoj1355 [Baltic2009]Radio Transmission
    poj1275 Cashier Employment
    bzoj3809 Gty的二逼妹子序列
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3265117.html
Copyright © 2011-2022 走看看