zoukankan      html  css  js  c++  java
  • [CF327E]Axis Walking([洛谷P2396]yyy loves Maths VII)

    题目大意:给一个长度为$n(1leqslant nleqslant24)$的序列$S$和$k(0leqslant kleqslant2)$个数。

    求有多少种$S$的排列方式使得其任何一个前缀和都不是$k$个数里的任意一个。

    题解:状压$DP$,枚举当前选的数的状态和下一个数,卡常,枚举下一个数的时候不可以直接枚举,要枚举$lowbit$看是从哪个数转移过来的,洛谷那道题特别卡常,需要开$O(2)$

    卡点:

    C++ Code:

    #include <cstdio>
    #define maxn 30
    #define N (1 << 24 | 5)
    const int mod = 1e9 + 7;
    int n, k;
    int s[maxn], _1, _2;
    inline long long fac(int n) {
    	long long res = 1;
    	for (int i = 2; i <= n; i++) res = res * i % mod;
    	return res;
    }
    
    int f[N], S[N];
    inline void up(int &a, int b) {if ((a += b) >= mod) a -= mod;}
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++) scanf("%d", s + i), S[1 << i - 1] = s[i];
    	scanf("%d", &k);
    	if (!k) return !printf("%lld
    ", fac(n));
    	switch (k) {
    		case 2: scanf("%d", &_2);
    		case 1: scanf("%d", &_1);
    	}
    	int U = 1 << n;
    	f[0] = 1;
    	for (register int i = 1; i < U; i++) {
    		int k = i & -i;
    		S[i] = S[i ^ k] + S[k];
    		if (S[i] != _1 && S[i] != _2) for (register int j = i; j; j &= j - 1) up(f[i], f[i ^ (j & -j)]);
    	}
    	printf("%d
    ", f[U - 1]);
    	return 0;
    }
    

      

  • 相关阅读:
    BZOJ3573: [Hnoi2014]米特运输
    BZOJ3531: [Sdoi2014]旅行
    BZOJ3505: [Cqoi2014]数三角形
    BZOJ3309: DZY Loves Math
    BZOJ3260: 跳
    BZOJ3252: 攻略
    BZOJ3226: [Sdoi2008]校门外的区间
    BZOJ3155: Preprefix sum
    BZOJ2843: 极地旅行社
    BZOJ2671: Calc
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9979105.html
Copyright © 2011-2022 走看看