• SDOI2008 sue的小球


    题目链接:戳我

    区间DP,设(dp[i][j][0/1])表示收集完([i,j])这个区间的小球之后,现在在左端点(0)或者右端点(1),损失掉的最小收益是多少。

    然后初始化只更新离初始点最近的两个点就行了qwq.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 1010
    using namespace std;
    int n;
    double dp[MAXN][MAXN][2],sum[MAXN];
    double all,x0;
    struct Node{double x,y,k;}node[MAXN];
    inline bool cmp(struct Node a,struct Node b){return a.x<b.x;}
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%lf",&n,&x0);
        for(int i=1;i<=n;i++) scanf("%lf",&node[i].x);
        for(int i=1;i<=n;i++) scanf("%lf",&node[i].y);
        for(int i=1;i<=n;i++) scanf("%lf",&node[i].k);
        sort(&node[1],&node[n+1],cmp);
        for(int i=1;i<=n;i++) sum[i]=sum[i-1]+node[i].k;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j][0]=dp[i][j][1]=1e9;
        bool flag=false;
        for(int i=1;i<=n;i++)
        {
            if(node[i].x>=x0&&flag==false)
            {
                flag=true;
                dp[i][i][0]=dp[i][i][1]=sum[n]*abs(x0-node[i].x);
                dp[i-1][i-1][0]=dp[i-1][i-1][1]=sum[n]*abs(x0-node[i-1].x);
            }
        }
        for(int i=n-1;i>=1;i--)
            for(int j=i+1;j<=n;j++)
            {
                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(node[i+1].x-node[i].x)*(sum[i]+sum[n]-sum[j]));
                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(node[j].x-node[i].x)*(sum[i]+sum[n]-sum[j]));
                dp[i][j][0]=min(dp[i][j][0],dp[i][j-1][1]+(2*node[j].x-node[j-1].x-node[i].x)*(sum[i-1]+sum[n]-sum[j-1]));
                dp[i][j][0]=min(dp[i][j][0],dp[i][j-1][0]+(2*node[j].x-2*node[i].x)*(sum[i-1]+sum[n]-sum[j-1]));
    
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(node[j].x-node[j-1].x)*(sum[i-1]+sum[n]-sum[j-1]));
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(node[j].x-node[i].x)*(sum[i-1]+sum[n]-sum[j-1]));
                dp[i][j][1]=min(dp[i][j][1],dp[i+1][j][0]+(node[i+1].x-2*node[i].x+node[j].x)*(sum[i]+sum[n]-sum[j]));
                dp[i][j][1]=min(dp[i][j][1],dp[i+1][j][1]+(2*node[j].x-2*node[i].x)*(sum[i]+sum[n]-sum[j]));
            }
        for(int i=1;i<=n;i++) all+=node[i].y;
        printf("%.3lf
    ",(all-min(1.0*dp[1][n][0],dp[1][n][1]))/1000.0);
        return 0;
    }
    
  • 相关阅读:
    英语在线单词、语法检查工具
    Excel操作:导出到Excel并下载到web客户端
    五度圈 Circle of Fifths
    【算法】新浪微博笔试题:找出共有2个以上标签的用户对
    云计算虚拟化可能不是你的菜
    也来聊聊Erlang
    云计算数据存储之购买指南
    聊聊云计算 从OpenStack说起
    WC2022不知道在干什么记
    Silverlight调用WCF服务引用
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10875028.html
Copyright © 2020-2023  润新知