【题解】APIO2007动物园

  首先一眼感受到这题特别的性质……5个?这么小的,感觉就像是状压。脑补了一下,如果没有环的话应该很好做吧……有环怎么办?5真的很小的,随便乱搞肯定也可以。那就放在外面暴力枚举吧。然后正解就出来了。

  然而这题题面真的有毒吧。说好的不能全部选走?我还多加了一个维度,结果数据里面允许全部取走……然后对于<5的点单独写了个爆搜。代码奇长……大家看看就好吧(以及位运算本人一贯以来又清奇又暴力的脑回路……)

  dp[][][0/1],1代表已经保留了至少一个动物……如果要A掉此题的话把转移那里加上dp[][][0]的就好了。整个namespace Speacial都是特判的点……(虽然数据里面并没有)

#include <bits/stdc++.h>
using namespace std;
#define CNST 32
#define maxn 10300
int n, c, tot, fans = 0, dp[maxn][CNST][2];
int num1[maxn * 5], num2[maxn * 5];
int lst[6] = {0, 1, 3, 7, 15, 31};
int fst[6] = {0, 16, 24, 28, 30, 31};
vector <int> V[maxn];

int read()
{
    int x = 0;
    char c;
    c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x;
}

void gmax(int &a, int b)
{
    a = a > b ? a : b;
}

void print(int x)
{
    int a[15], tot = 0;
    a[5] = a[4] = a[3] = a[2] = a[1] = 0;
    while(x)
    {
        a[++ tot] = x & 1;
        x >>= 1;
    }
    for(int i = 5; i; i --)
        printf("%d", a[i]);
    return;
}

void work(int x, int sum, int opt)
{
    int tem = 0;
    for(vector <int> :: iterator i = V[x].begin(); i < V[x].end(); i ++)
    {
        int k = *i;
        if((sum & num2[k]) || (num1[k] > (sum & num1[k]))) tem ++;
    }
    dp[x][sum][opt] += tem;
    int k1 = (sum << 1) & (fst[4]), k2 = (((sum << 1) & (fst[4])) | 1);
    gmax(dp[x + 1][k1][opt], dp[x][sum][opt]);
    gmax(dp[x + 1][k2][1], dp[x][sum][opt]);
}

int Check(int now, int sum)
{
    int ans = 0;
    for(int i = 1; i <= 4; i ++)
    {
        int a = now, b = sum, t = 0;
        t = a & (lst[5 - i]); t <<= i;
        t |= ((b & (fst[i])) >> (5 - i));
        for(vector <int> :: iterator j = V[i].begin(); j < V[i].end(); j ++)
        {
            int k = *j;
            if((t & num2[k]) || (num1[k] > (t & num1[k]))) ans ++;
        }
    }
    return ans;
}

int DP(int sum, int opt)
{
    memset(dp, -1, sizeof(dp));
    int ans = 0;
    dp[5][sum][opt] = 0;
    work(5, sum, opt);
    for(int i = 6; i <= n; i ++)
    {
        int maxx = 0;
        for(int j = 0; j < CNST; j ++)
            for(int k = 0; k <= 1; k ++)
            {
                if(~dp[i][j][k]) work(i, j, k);
                maxx = max(maxx, dp[i][j][k]);
            }
    }    
    for(int j = 0; j < CNST; j ++)
    {
        if(dp[n][j][1] == -1) continue;
        int p = Check(j, sum);
        ans = max(ans, p + dp[n][j][1]);
    }
    return ans;
}

void dfs(int x, int sum)
{
    if(x == 5)
    {
        sum <<= 1;
        if(sum & (CNST - 1)) fans = max(fans, DP(sum, 1));
        else fans = max(fans, DP(sum, 0));
        sum |= 1;
        fans = max(fans, DP(sum, 1));
        return;
    }
    sum <<= 1;
    dfs(x + 1, sum);
    dfs(x + 1, sum |= 1);
}

int main()
{
    n = read(), c = read();
    for(int i = 1; i <= c; i ++)
    {
        int E = read(), F = read(), L = read();
        int id = E + 4; if(id > n) id -= n;
        V[id].push_back(++ tot);
        for(int j = 1; j <= F; j ++) //害怕 
        {
            int x = read(); x = id - x;
            if(x < 0) x += n;
            num1[tot] |= (1 << x); 
        }
        for(int j = 1; j <= L; j ++) //喜欢 
        {
            int x = read(); x = id - x;
            if(x < 0) x += n;
            num2[tot] |= (1 << x);
        }
    }
    dfs(1, 0);
    printf("%d\n", fans);
    return 0;
} 

 

转载于:https://www.cnblogs.com/twilight-sx/p/9024871.html

Stkcd [股票代码] ShortName [股票简称] Accper [统计截止日期] Typrep [报表类型编码] Indcd [行业代码] Indnme [行业名称] Source [公告来源] F060101B [净利润现金净含量] F060101C [净利润现金净含量TTM] F060201B [营业收入现金含量] F060201C [营业收入现金含量TTM] F060301B [营业收入现金净含量] F060301C [营业收入现金净含量TTM] F060401B [营业利润现金净含量] F060401C [营业利润现金净含量TTM] F060901B [筹资活动债权人现金净流量] F060901C [筹资活动债权人现金净流量TTM] F061001B [筹资活动股东现金净流量] F061001C [筹资活动股东现金净流量TTM] F061201B [折旧摊销] F061201C [折旧摊销TTM] F061301B [公司现金流1] F061302B [公司现金流2] F061301C [公司现金流TTM1] F061302C [公司现金流TTM2] F061401B [股权现金流1] F061402B [股权现金流2] F061401C [股权现金流TTM1] F061402C [股权现金流TTM2] F061501B [公司自由现金流(原有)] F061601B [股权自由现金流(原有)] F061701B [全部现金回收率] F061801B [营运指数] F061901B [资本支出与折旧摊销比] F062001B [现金适合比率] F062101B [现金再投资比率] F062201B [现金满足投资比率] F062301B [股权自由现金流] F062401B [企业自由现金流] Indcd1 [行业代码1] Indnme1 [行业名称1] 季度数据,所有沪深北上市公司的 分别包含excel、dta数据文件格式及其说明,便于不同软件工具对数据的分析应用 数据来源:基于上市公司年报及公告数据整理,或相关证券交易所、各部委、省、市数据 数据范围:基于沪深北证上市公司 A股(主板、中小企业板、创业板、科创板等)数据整理计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值