zoukankan      html  css  js  c++  java
  • 2018icpc南京网络赛-E AC Challenge(状压+dfs)

    题意:

    n道题,每道题有ai和bi,完成这道题需要先完成若干道题,完成这道题可以得到分数t*ai+bi,其中t是时间

    1s, n<=20

    思路:

    由n的范围状压,状态最多1e6

    然后dfs,注意代码中dfs里的剪枝,

    对一个状态statu,因为贪心的取最大值就行,所以及时剪枝

    代码:

    当时写不出来真是菜的活该

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 2e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const ll Inf = 0x3f3f3f3f3f3f3f3f;
    const db pi = acos(-1.0);
    int n;
    ll dp[maxn];//达到status的最大值
    ll a[30], b[30];
    int s[30];
    vector<int>nd[30];
    void init(){
        for(int i = 1; i <= n; i++){
            int ans = 0;
            int sz = nd[i].size();
            for(int j = 0; j < sz; j++){
                ans|=(1<<(nd[i][j]-1));
            }
            s[i]=ans;
        }
        return;
    }
    void dfs(int cnt, int statu, ll ans){
        dp[statu] = max(dp[statu], ans);
        if(cnt == n)return;
        for(int i = 1; i <= n; i++){
            if(((1<<(i-1))&statu)!=0)continue;
            if((s[i]&statu)!=s[i])continue;
            dfs(cnt+1,statu|(1<<(i-1)), ans + (cnt+1)*a[i]+b[i]);
        }
        return;
    }
    int main(){
        mem(dp,-1);
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            int num;
            scanf("%lld %lld %d", &a[i], &b[i], &num);
            for(int j = 0; j < num; j++){
                int x;
                scanf("%d",&x);
                nd[i].pb(x);
            }
        }
        init();
        dfs(0,0,0);
        printf("%lld",dp[(1<<n)-1]<0?0:dp[(1<<n)-1]);
        return 0;
    }
    
    /*
    
     */
  • 相关阅读:
    后台服务器经典面试题
    Java英语面试题(核心知识篇)
    Java常用英语汇总(面试必备)
    字符压缩编码
    外排序
    基数排序
    Windows Server 2008 R2 部署服务
    LINUX中常用操作命令
    我的学习笔记_Windows_HOOK编程 2009-12-03 11:19
    CSDN-Code平台使用过程中的5点经验教训
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10182537.html
Copyright © 2011-2022 走看看