zoukankan      html  css  js  c++  java
  • [APIO2007]动物园

    状压DP

    先预处理出来pre[i][S]表示对于第i个位置,往后5个的状态是S时,开心的小朋友的数量。

    然后dp的时先枚举前5个的状态,再dp。

    因为围栏是环状的,之后统计答案时统计的是那个f[n][S]=startS的。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m,hsta,lsta,pre[10005][33],f[10005][33],cnt;
    void Dfs(int E,int dep,int sta) {
        if(dep==5) {
            if(sta&lsta||(sta&hsta)!=hsta) pre[E][sta]++;
            return;
        }
        Dfs(E,dep+1,sta|(1<<dep));
        Dfs(E,dep+1,sta);
    }
    int main() {
        scanf("%d%d",&m,&n);
        for(int i=1,e,h,l,x;i<=n;i++) {
            scanf("%d%d%d",&e,&h,&l);
            hsta=lsta=0;
            while(h--) scanf("%d",&x),x=(x-e+m)%m,hsta|=(1<<x);
            while(l--) scanf("%d",&x),x=(x-e+m)%m,lsta|=(1<<x);
            Dfs(e,0,0);
        }
        int ans=0;
        for(int S=0;S<32;S++) {
            memset(f[0],0xcf,sizeof f[0]);
            f[0][S]=0;
            for(int i=1;i<=m;i++)
                for(int j=0;j<32;j++)
                    f[i][j]=max(f[i-1][(j&15)<<1],f[i-1][(j&15)<<1|1])+pre[i][j];
            ans=max(ans,f[m][S]);
        }
        cout<<ans<<endl;
        return 0;
    }
    动物园
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    SQL里面的函数应用
    Split的小用法
    堆栈和堆问题
    break,continue,goto,Return几个方法
    接口笔记
    抽象类
    虚方法
    将博客搬至CSDN
    运行数据区
    美团-走迷宫
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9773160.html
Copyright © 2011-2022 走看看