hihocoder 1315 Reachable Permutations

题目链接

官方题解

没有搜到民间题解。自己写一份咯。
插入一张样例的解法的图片。

阅读题解之后加上这个图,应该就差不多了。
代码参考抄袭当时比赛第二的shinerain的代码。
位运算运用的好优雅。

#include <algorithm>
#include <cstdio>
#include <iostream>

#define rin freopen("in.txt","r",stdin)
#define rout freopen("1.out","w",stdout)
#define Del(a, b) memset(a,b,sizeof(a))
typedef long long LL;
using namespace std;
const int MOD=1e9+7;
int n;
int calone[(1 << 20) + 7], f[(1 << 20) + 7], a[23];

int cmp(int a, int b) {
    if (!a && !b)return 1;
    int t1 = a & (-a), t2 = b & (-b);//a的最后一个1出现的位置
    if (t1 <= t2)return cmp(a ^ a & (-a), b ^ b & (-b));
    else return 0;
}

int main() {
    rin;
    scanf("%d", &n);
    int t;
    for (int i = 0; i < n; i++)scanf("%d", &t),a[t]=1<<i;
    for (int i = 0; i < n; i++)a[i + 1] |= a[i];
    f[0]=1;
    for (int i = 0; i < (1 << n); i++) {
        calone[i] = calone[i >> 1] + (i & 1);
        if (!cmp(i, a[calone[i]]))continue;
        for(int j=0;j<n;j++)
            if(i>>j&1^1)
                f[i^1<<j]=(f[i^1<<j]+f[i])%MOD;
    }
    printf("%d\n",f[(1<<n)-1]);
    return 0;
}
posted @ 2017-12-06 18:12  Belleaholic  阅读(266)  评论(0)    收藏  举报