• ACM-ICPC 2018 南京赛区网络预赛 E AC Challenge 状压dp


    题目链接:AC Challenge

    题意:题意就是有n个问题(最多20),你在做这个问题之前要做指定si个问题.然后做完这个问题你会得到a【i】*T+b[i]的分数。问最多能得多少分(大概是这意思).

    题解:由于题目数比较小很容易想到状压,用f[i]保存第i个问题需要先解决哪些问题。然后dp[i][j]表示做到第i个问题,j是集合表示已经做过哪些问题

    状态转移就很容易了

    #include<string.h>
    #include<bits/stdc++.h>
    #include<algorithm>
    #include<queue>
    #define ll long long
    #define pb push_back
    using namespace std;
    #define INF 0xffffff
    #define MAXN 300010
    const int N=(1<<20)+10;
    int n,f[25],a[25],b[25],s[25];
    ll dp[2][N];
    bool vis[2][N];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d",&a[i],&b[i],&s[i]);
            for(int j=0;j<s[i];j++)
            {
                int x;
                scanf("%d",&x);
                f[i]|=1<<(x-1);
            }
        }
        ll ans=0;
       vis[0][0]=1;
       int tmp=0;
        for(int t=1;t<=n;t++)
        {
            for(int i=0;i<(1<<n);i++)
            {
                vis[tmp^1][i]=0;
            }
            for(int i=0;i<(1<<n);i++)
            {
                if(!vis[tmp][i])continue;
                for(int j=1;j<=n;j++)
                {
                    if((i>>(j-1))&1)continue;
                    if(!f[j]||(f[j]&i)==f[j])
                    {
                        int to=i|(1<<(j-1));
                        dp[tmp^1][to]=max(dp[tmp^1][to],dp[tmp][i]+1ll*a[j]*t+b[j]);
                        vis[tmp^1][to]=1;
                        ans=max(ans,dp[tmp^1][to]);
                    }
                }
            }
            tmp^=1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    2
    5 6 0
    4 5 1 1
    */
  • 相关阅读:
    春秋战国时期灭了三个国家的陈国女人
    学历史有什么用?
    真正的奴才韩非
    深度学习的历史
    深度学习三十年
    图算法
    几种常见的查找算法
    数据结构之基于堆的优先队列
    几种常见的排序算法
    数据结构(背包、队列和栈)
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9642415.html
Copyright © 2020-2023  润新知