码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 327E Axis Walking(状压DP+卡常技巧)

时间:2018-07-30 11:19:21      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:OWIN   font   cstring   bsp   poi   cal   friend   uri   题解   

Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub lives at point 0 and Iahubina at point d.

Iahub has n positive integers a1a2, ..., an. The sum of those numbers is d. Suppose p1p2, ..., pn is a permutation of {1, 2, ..., n}. Then, let b1 = ap1b2 = ap2and so on. The array b is called a "route". There are n! different routes, one for each permutation p.

Iahub‘s travel schedule is: he walks b1 steps on Ox axis, then he makes a break in point b1. Then, he walks b2 more steps on Ox axis and makes a break in point b1 + b2. Similarly, at j-th (1 ≤ j ≤ n) time he walks bj more steps on Ox axis and makes a break in point b1 + b2 + ... + bj.

Iahub is very superstitious and has k integers which give him bad luck. He calls a route "good" if he never makes a break in a point corresponding to one of those knumbers. For his own curiosity, answer how many good routes he can make, modulo 1000000007 (109 + 7).

Input

The first line contains an integer n (1 ≤ n ≤ 24). The following line contains nintegers: a1, a2, ..., an (1 ≤ ai ≤ 109).

The third line contains integer k (0 ≤ k ≤ 2). The fourth line contains k positive integers, representing the numbers that give Iahub bad luck. Each of these numbers does not exceed 109.

题意:给出n个数,给出至多两个数k1,k2,求这n个数每个排列中前缀和不含k1/k2的排列个数

题解:首先看着范围考虑状压dp

dp[sta]=sigma(dp[sta^1<<i]) i为sta中所有1的位置

sum[sta]==k1||sum[sta]==k2 dp[sta]=0;

然后显然直接模会非常慢, 所以用-mod代替模

 

代码如下:

#pragma GCC optimize(3)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mod 1000000007
using namespace std;

long long n,dp[1<<24],sum[1<<24],kkk[2],k;

inline int lowbit(int x)
{
    return x&-x;
}

int main()
{
    scanf("%lld",&n);
    int tmp;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&tmp);
        sum[1<<i]=tmp;
    }
    scanf("%lld",&k);
    for(int i=0;i<k;i++)
    {
        scanf("%lld",&kkk[i]);
    }
    dp[0]=1;
    for(int i=1;i<(1<<n);i++)
    {
        sum[i]=sum[i^lowbit(i)]+sum[lowbit(i)];
        if(sum[i]==kkk[1]||sum[i]==kkk[0])
        {
            continue;
        }
        for(int j=i;j;j-=lowbit(j))
        {
            dp[i]=dp[i]+dp[i^lowbit(j)];
            if(dp[i]>=mod) dp[i]-=mod;
        }
    }
    printf("%lld\n",dp[(1<<n)-1]);
}

 

CodeForces 327E Axis Walking(状压DP+卡常技巧)

标签:OWIN   font   cstring   bsp   poi   cal   friend   uri   题解   

原文地址:https://www.cnblogs.com/stxy-ferryman/p/9388853.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!