题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

Posted yuanqiqhfz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows相关的知识,希望对你有一定的参考价值。

题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

题目链接

数据规模16-20的都是状压

如果要每一位都压序号的话空间肯定是不够的,所以每一位只能是0或1。1表示有这头牛,0表示没有这头牛。显然每个位置的选择和他两边的牛有关,所以我们就可以定义这样的状态:

f[i][j]表示使用集合i的牛,其中最后一头牛的序号为j时的总方案数。答案从f[(1 << n) - 1][n]累加即可。

转移也比较好想,从i中枚举选出倒数第二头牛,作为子状态的最后一头牛,注意边界情况。

下面看代码吧,也不是很难:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define N 17
using namespace std;
inline int read()

    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')  if (c == '-') f = -1; c = getchar(); 
    while (c >= '0' && c <= '9')  x = x * 10 + c - '0'; c = getchar(); 
    return x * f;

int abs(int x)  return x > 0 ? x : -x; 
ll f[(1 << 16) + 5][18], ans;
int n, k, a[N], cnt[(1 << 16) + 5];
void init()

    for (int i = 1; i <= (1 << n); i++)
    
        for (int j = 0; j < n; j++)
        
            if (i & (1 << j)) cnt[i]++;
        
    
//初始化每种集合的奶牛头数
int main()

    n = read(), k = read();
    for (int i = 1; i <= n; i++)
        a[i] = read();
    init();
    for (int i = 1; i < (1 << n); i++)
        for (int j = 1; j <= n; j++) //枚举这个集合的最后一头牛
            if (i & (1 << (j - 1)))
            
                if (cnt[i] == 1) f[i][j] = 1; //边界情况
                else
                    for (int p = 1; p <= n; p++) //枚举倒数第二头牛
                        if (p != j && (i & (1 << (p - 1))) && abs(a[p] - a[j]) > k)
                            f[i][j] += f[i - (1 << (j - 1))][p];
            
    for (int i = 1; i <= n; i++)
        ans += f[(1 << n) - 1][i];
    cout << ans;
    return 0;

19.09.05

以上是关于题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows的主要内容,如果未能解决你的问题,请参考以下文章

P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

题解Luogu2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

[USACO08NOV]奶牛混合起来Mixed Up Cows