计蒜客 30994 - 2018ICPC南京网络预赛 - E题 - AC Challenge - 状压DP

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/sdau20163942/article/details/82319695

题解来自IGVA大佬:https://blog.csdn.net/LSD20164388/article/details/82313223

题目链接https://nanti.jisuanke.com/t/30994

题意:有n个问题编号为1~n,每个问题给出ai,bi,si,以及pi1,pi2,pi3...pij...pisi,1<=j<=si,分别代表第t分钟解决这个问题可以得到t×ai​+bi​的分数,si代表课i有si门前导前导分别为pi1...pisi,只有前导问题全部解决当前问题才能解决;现在每一分钟可以解决1个问题,得到相应的价值(价值可能为负),可以在任意时间放弃答题,问最大得到多少分。

解析:注意n的范围是0<n<=20,那么往dfs以及状压dp想,发现是比较裸的状压dp,状压不是很熟悉,是队友A的,但代码很容易看懂。

代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define ll long long
using namespace std;
const int mo=1e9+7;
const int maxn=1<<20;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n,m,k,T;
ll dp[maxn],ans,tmp,sum;
ll a[25],c[25],b[25];
ll fcount(int x)//计算x的二进制里有几个1
{
 ll s=0;
 while(x){
  s++;
  x&=(x-1);
 }
    return s;
}
int main() {
     int T;
     while(scanf("%d",&n)!=EOF)
     {
         ans=0;sum=0;
         for(int i=0;i<n;i++)
         {
             scanf("%lld%lld%d",&a[i],&b[i],&k);
             c[i]=0;
             for(int j=0;j<k;j++)
             {
                 int x;
                 scanf("%d",&x);
                 x--;
                 c[i]|=(1<<x);//c[i]保存所有前导问题
             }
         }
         m=1<<n;
         for(int i=0;i<m;i++)//m就是所有状态数,即2^n
         dp[i]=-inf;//数据水了,这里改成-1也能过,实际上-1不一定不合法
         dp[0]=0;//一道题都没做
         for(int i=1;i<m;i++)//枚举每种状态
         {
             for(int j=0;j<n;j++)//枚举判断问题j是否要解
             if(i&(1<<j))//如果问题j要解
             {
                 int tmp=i^(1<<j);//没选问题j的状态,即假设的之前选过的所有课
                 if(dp[tmp]==-inf) continue;
                 if((tmp|c[j])==tmp)//前导问题已经全部解决
                 {
                     ll t=fcount(i);//共解决了t个问题,即当前为第t分钟
                     dp[i]=max(dp[i],dp[tmp]+a[j]*t+b[j]);
                     ans=max(ans,dp[i]);
                 }
             }
         }
         printf("%lld\n",ans);
     }
    return 0;
}

 

猜你喜欢

转载自blog.csdn.net/sdau20163942/article/details/82319695