zoukankan      html  css  js  c++  java
  • 【BZOJ-4380】Myjnie 区间DP

    4380: [POI2015]Myjnie

    Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special Judge
    Submit: 162  Solved: 82
    [Submit][Status][Discuss]

    Description

    有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]。
    有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于c[i],那么这个人就不洗车了。
    请给每家店指定一个价格,使得所有人花的钱的总和最大。

    Input

    第一行包含两个正整数n,m(1<=n<=50,1<=m<=4000)。
    接下来m行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<=b[i]<=n,1<=c[i]<=500000)

    Output

    第一行输出一个正整数,即消费总额的最大值。
    第二行输出n个正整数,依次表示每家洗车店的价格p[i],要求1<=p[i]<=500000。
    若有多组最优解,输出任意一组。

    Sample Input

    7 5
    1 4 7
    3 7 13
    5 6 20
    6 7 1
    1 2 5

    Sample Output

    43
    5 5 13 13 20 20 13

    HINT

    Source

    鸣谢Claris

    Solution

    这个区间dp好厉害啊,自己的转移并没有想到,最后是看着Claris的课件做的。

    现将$c_{i}$离散化,然后区间dp

    $dp[l][r][p]$表示区间$[l,r]$,最小价值为$p$的最大总和,$cnt[k][c]$表示经过$k$位置的费用$geqslant c$的数量

    转移时通过枚举最小值所在的位置$k$,来进行转移$dp[l][r][p]<--dp[l][k-1][p]+dp[k+1][r][p]+cost(k)$

    还要记录方案,最后用dfs输出。

    总的时间复杂度$O(N^{3}M)$

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int N,M,a[5050],b[5050],c[5050],C[5050],price[5050],ls[5050],tp,top;
    int from[55][55][5050],last[55][55][5050],cnt[55][5050],dp[55][55][5050];
    inline void Get(int l,int r,int p)
    {
        if (l>r) return;
        int fr=from[l][r][p],la=last[l][r][p];
    //    printf("%d  %d  %d  %d
    ",l,r,p,fr);
        price[fr]=C[la];
        Get(l,fr-1,la); Get(fr+1,r,la);
    }
    int main()
    {
        N=read(),M=read();
        for (int i=1; i<=M; i++) a[i]=read(),b[i]=read(),C[i]=c[i]=read(),ls[++tp]=c[i];
        sort(ls+1,ls+tp+1);
        for (int i=1; i<=tp; i++) if (ls[top]!=ls[i]) ls[++top]=ls[i];
        for (int i=1,x; i<=M; i++) x=lower_bound(ls+1,ls+top+1,c[i])-ls,C[x]=c[i],c[i]=x;
    //    for (int i=1; i<=M; i++) printf("%d  ",C[i]); puts("");
        for (int l=1; l<=N; l++)
            for (int r=l; r<=N; r++)
                for (int p=1; p<=M; p++)
                    dp[l][r][p]=-0x3fffffff;
        for (int len=1; len<=N; len++)
            for (int l=1,r=l+len-1; r<=N; l++,r++)
                {
                    for (int k=l; k<=r; k++)
                        for (int i=1; i<=M; i++)
                            cnt[k][i]=0;
                    for (int i=1; i<=M; i++)
                        if (a[i]>=l && b[i]<=r)
                            for (int k=a[i]; k<=b[i]; k++)
                                cnt[k][c[i]]++;
                    for (int k=l; k<=r; k++)
                        for (int i=M-1; i; i--)
                            cnt[k][i]+=cnt[k][i+1];
                    for (int k=l; k<=r; k++)
                        for (int i=1; i<=M; i++)
                            if (dp[l][k-1][i]+dp[k+1][r][i]+C[i]*cnt[k][i]>dp[l][r][i])
                                dp[l][r][i]=dp[l][k-1][i]+dp[k+1][r][i]+C[i]*cnt[k][i],
                                from[l][r][i]=k,last[l][r][i]=i;// from[l][r][i]=i;
                    for (int i=M-1; i; i--)
                        if (dp[l][r][i]<dp[l][r][i+1])
                            dp[l][r][i]=dp[l][r][i+1],
                            from[l][r][i]=from[l][r][i+1],last[l][r][i]=last[l][r][i+1];
    //                printf("<%d , %d> == %d
    ",l,r,dp[l][r][1]);
                }
        printf("%d
    ",dp[1][N][1]);
        Get(1,N,1);
        for (int i=1; i<=N; i++) printf("%d ",price[i]);
        return 0;
    }
  • 相关阅读:
    利用win10自带的虚拟机Hyper-V安装Centos7的步骤教程
    Java元组Tuple介绍与使用
    Fiddler高级用法-设置断点
    Fiddler高级用法-抓取手机app数据包
    Fiddler基础用法-抓取浏览器数据包
    dig 命令
    curl 命令
    vmware虚拟机三种网络连接方式
    解决虚拟机vmware虚拟机安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题
    linux 文件系统 xfs、ext4、ext3 的区别
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/6052067.html
Copyright © 2011-2022 走看看