zoukankan      html  css  js  c++  java
  • BZOJ4380: [POI2015]Myjnie

    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
     
    将所有c[i]离散,设f[l][r][j]表示[l,r]区间内,最小值>=j的收益。
    设g[x][j]表示所有[l,r]中c[i]>=j的区间个数,即每个人的贡献,然后序列DP即可。
    时间复杂度为O(N^3*M)
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
    	if(head==tail) {
    		int l=fread(buffer,1,BufferSize,stdin);
    		tail=(head=buffer)+l;
    	}
    	return *head++;
    }
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=55;
    const int maxm=4005;
    int n,m,B[maxn],s[maxm],t[maxm],A[maxm],tmp[maxm];
    int f[maxn][maxn][maxm],p[maxn][maxn][maxm],g[maxn][maxm];
    void print(int l,int r,int j) {
    	if(l>r) return;
    	int x=p[l][r][j];
    	if(!x) print(l,r,j+1);
    	else print(l,x-1,j),B[x]=tmp[j],print(x+1,r,j);
    }
    int main() {
    	n=read();m=read();
    	rep(i,1,m) s[i]=read(),t[i]=read(),A[i]=tmp[i]=read();
    	sort(tmp+1,tmp+m+1);
    	rep(i,1,m) A[i]=lower_bound(tmp+1,tmp+m+1,A[i])-tmp;
    	dwn(l,n,1) rep(r,l,n) {
    		rep(i,l,r) rep(j,1,m) g[i][j]=0;
    		rep(j,1,m) if(l<=s[j]&&t[j]<=r) g[s[j]][A[j]]++,g[t[j]+1][A[j]]--;
    		rep(i,l,r) rep(j,1,m) g[i][j]+=g[i-1][j];
    		rep(i,l,r) dwn(j,m,2) g[i][j-1]+=g[i][j];
    		dwn(j,m,1) {
    			int& ans=f[l][r][j];
    			rep(x,l,r) {
    				int res=f[l][x-1][j]+f[x+1][r][j]+tmp[j]*g[x][j];
    				if(res>=ans) p[l][r][j]=x,ans=res;
    			}
    			if(f[l][r][j+1]>ans) {
    				ans=f[l][r][j+1];
    				p[l][r][j]=0;
    			}
    		}
    	}
    	printf("%d
    ",f[1][n][1]);
    	print(1,n,1);
    	rep(i,1,n) printf("%d%c",B[i],i==n?'
    ':' ');
    	return 0;
    }
    

      

  • 相关阅读:
    Linux IO接口 监控 (iostat)
    linux 防火墙 命令
    _CommandPtr 添加参数 0xC0000005: Access violation writing location 0xcccccccc 错误
    Visual Studio自动关闭
    Linux vsftpd 安装 配置
    linux 挂载外部存储设备 (mount)
    myeclipse 9.0 激活 for win7 redhat mac 亲测
    英文操作系统 Myeclipse Console 乱码问题
    Linux 基本操作命令
    linux 查看系统相关 命令
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5413982.html
Copyright © 2011-2022 走看看