zoukankan      html  css  js  c++  java
  • B4197 [Noi2015]寿司晚宴 状压dp

    这个题一开始想到了唯一分解定理,然后状压。但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了。

    然后正常状压dp就很好搞了。

    题干:

    Description
    
    为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。
    在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 1,2,3,…,n−1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n)。
    现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y 的寿司,而 x 与 y 不互质。
    现在小 G 和小 W 希望统计一共有多少种和谐的品尝寿司的方案(对给定的正整数 p 取模)。注意一个人可以不吃任何寿司。
    Input
    输入文件的第 1 行包含 2 个正整数 n,p,中间用单个空格隔开,表示共有 n 种寿司,最终和谐的方案数要对 p 取模。
    Output
    输出一行包含 1 个整数,表示所求的方案模 p 的结果。
    Sample Input
    3 10000
    Sample Output
    9
    HINT
     2≤n≤500
    0<p≤1000000000

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    const int mod = 998244353;
    typedef double db;
    typedef long long ll;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            {x = x * 10 + c - '0';}
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    ll pri[12] = {0,2,3,5,7,11,13,17,19,0};
    struct node
    {
        ll val,big,s;
        void init()
        {
            ll tmp = val;
            big = -1;
            duke(i,1,8)//only
            {
                if(tmp % pri[i]) continue;
                s |= (1 << (i - 1));
                while(tmp % pri[i] == 0)
                tmp /= pri[i];
            }
            if(tmp != 1)
            big = tmp;
        }
    }a[1010];
    bool cmp(node a,node b)
    {
        return a.big < b.big;
    }
    ll n;
    ll p;
    ll pl(ll l,ll r)
    {
        l += r;
        return l >= p ? l - p : l;
    }
    ll f1[300][300],f2[300][300];
    ll dp[300][300];
    int main()
    {
        read(n);read(p);
        duke(i,2,n)
        a[i - 1].val = i,a[i - 1].init();
        sort(a + 1,a + n,cmp);
        dp[0][0] = 1;
        duke(i,1,n - 1)
        {
            if(i == 1 || a[i].big != a[i - 1].big || a[i].big == -1)
            {
                memcpy(f1,dp,sizeof(f1));
                memcpy(f2,dp,sizeof(f2));
            }
            lv(j,255,0)
            {
                lv(k,255,0)
                {
                    if(j & k) continue;
                    if((a[i].s & j) == 0)
                    f2[j][k | a[i].s] = pl(f2[j][k | a[i].s],f2[j][k]);
                    if((a[i].s & k) == 0)
                    f1[j | a[i].s][k] = pl(f1[j | a[i].s][k],f1[j][k]);
                }
            }
            if(i == n - 1 || a[i].big != a[i + 1].big || a[i].big == -1)
            {
                duke(j,0,255)
                {
                    duke(k,0,255)
                    {
                        if(j & k) continue;
                        dp[j][k] = pl(f1[j][k],pl(f2[j][k],p - dp[j][k]));
                    }
                }
            }
        }
        ll ans = 0;
        duke(j,0,255)
        {
            duke(k,0,255)
            {
                if((j & k) == 0 && dp[j][k])
                ans = pl(ans,dp[j][k]);
    //            cout<<dp[j][k]<<" ";
            }
    //        cout<<endl;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    @Transactional事务不起作用原因
    Date类型错误
    springboot整合mybatis(注解)
    springcloud(六):Spring Cloud 配置中心采用数据库存储配置内容
    Mybatis系列(二)配置
    spring boot日志logback输出
    spring boot不使用resoures而是建立一个conf
    spring boot使用guava缓存
    OrCAD生成网表
    OrCAD创建原理图符号图
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9751717.html
Copyright © 2011-2022 走看看