zoukankan      html  css  js  c++  java
  • 2018-2019 ACM-ICPC Brazil Subregional Programming Contest F. Music Festival

    题目:https://codeforces.com/gym/101908/problem/F

    题意:给你n个舞台,每个舞台有很多个节目,每个节目有个开始时间,结束时间,价值,每个舞台至少出演过一个节目,所有舞台同一时刻只能一个舞台演节目,求怎么安排节目有最大价值

    思路:首先舞台数只有10,而且我们必须访问每个舞台至少一次,很明显是个状态   1<<10 ,分别代表每个舞台现在演过节目没有,然后很明显我们还有有一个区间状态。

    如果题目没有要求每个舞台必须演一次的话,很明显这个问题我们就可以直接按左端点排序,dp[end]=max(dp[1-begin]+val,dp[end]),我们记录下1-begin的最大值,pre,然后我们就能轻松求出来。这题多了每个舞台访问一次的要求其实是一样的道理,我们每次用pre数组更新出每个状态j的区间里面最大值

    dp[i][j]   代表 前i个节目    状态j (舞台是否表演过的情况)

    pre[j][k]     代表 状态j        1-k区间的最大值是多少

    #include<bits/stdc++.h>
    #define maxn 1100
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    struct sss{
        int id,val;
        int be,ed;
    }a[10005];
    int q[100005];
    int dp[maxn][maxn];
    int pre[maxn][maxn<<1];
    int n,m,num,len;
    int cmp(struct sss x,struct sss y){
        if(x.be==y.be) return x.ed<y.ed;
        return x.be<y.be;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&m);
            for(int j=0;j<m;j++){
                scanf("%d%d%d",&a[num].be,&a[num].ed,&a[num].val);
                q[++len]=a[num].be;
                q[++len]=a[num].ed;
                a[num++].id=i;
            }
        }
        sort(q+1,q+len+1);
        len=unique(q+1,q+len+1)-q-1;
        sort(a,a+num,cmp);
        int flag=0;
        int mx=-1;
        int dex=1;
        int M=(1<<n)-1;
        for(int i=0;i<num;i++){
            a[i].be=lower_bound(q+1,q+len+1,a[i].be)-q;
            a[i].ed=lower_bound(q+1,q+len+1,a[i].ed)-q;
            while(dex<=a[i].be){
                for(int j=1;j<=M;j++){
                    pre[j][dex]=max(pre[j][dex],pre[j][dex-1]);
                }
                dex++;
            }
            int t=1<<a[i].id; 
            dp[i][t]=a[i].val;
            pre[t][a[i].ed]=max(pre[t][a[i].ed],a[i].val);
            for(int j=1;j<=M;j++){
              if(pre[j][a[i].be]) 
                dp[i][j|t]=max(dp[i][j|t],pre[j][a[i].be]+a[i].val);
            }
            for(int j=1;j<=M;j++){
              if(dp[i][j]) pre[j][a[i].ed]=max(pre[j][a[i].ed],dp[i][j]);
              }
            mx=max(mx,dp[i][M]);
        }
    
        if(mx==0) mx=-1;
        printf("%d",mx);
        return 0;
    } 
    View Code
  • 相关阅读:
    OSPF
    【今日CS 视觉论文速览】 24 Jan 2019
    【今日CS 视觉论文速览】Wed, 23 Jan 2019
    【今日CS 视觉论文速览】 21 Jan 2019
    【Processing学习笔记】安装与入门
    【今日CS 视觉论文速览】Part2, 18 Jan 2019
    【今日CS 视觉论文速览】Fri, 18 Jan 2019
    【今日CS 视觉论文速览】Thu, 17 Jan 2019
    【今日CS 视觉论文速览】Part2, 16 Jan 2019
    【今日CS 视觉论文速览】Wed, 16 Jan 2019
  • 原文地址:https://www.cnblogs.com/Lis-/p/11382945.html
Copyright © 2011-2022 走看看