题解 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

原文地址:https://www.cnblogs.com/YuanqiQHFZ/p/11622352.html

时间: 2024-10-25 08:27:25

题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows的相关文章

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

P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i <= 25,000). The cows are so proud of it that each one now wears her number in a gangsta manner engraved in large le

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

—————————————————————————————————————————————————————————— 我真睿智 重叠变量名查了十多分钟的错 很好的状压题,无论是隐形的表示还有计数 ———————————————————————————— #include<bits/stdc++.h> using namespace std; long long int n,kk,ans,a[17],f[17][1<<17],cows[17]; int main() { cin>

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

类似于n皇后的思想,只要把dfs表示放置情况的数字压缩成一个整数,就能实现记忆化搜索了. 一些有关集合的操作: {i}在集合S内:S&(1<<i)==1: 将{i}加入集合S:S=S|(1<<i): 集合S内包含了{0,1,2,...,n-2,n-1}:S==(1<<n)-1: 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 using namespa

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

题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i <= 25,000). The cows are so proud of it that each one now wears her number in a gangsta manner engraved in large letters on a gold plate hung around her

[luoguP2915] [USACO08NOV]奶牛混合起来Mixed Up Cows(DP)

传送门 f[i][S] 表示当前集合为 S,最后一个数为 i 的最优解 f[i][S] += f[j][S - i] (j, i ∈ S && j != i && abs(a[i] - a[j]) > k) ——代码 1 #include <cstdio> 2 #include <iostream> 3 #define LL long long 4 5 int a[17]; 6 int n, m, k; 7 LL ans, f[17][1 &l

Luogu2917_ [USACO08NOV]奶牛混合起来Mixed Up Cows_KEY

题目传送门 看到数据范围就果断装压. 设f[i][j]表示i状态下最后一个数字为a[j]. code: #include <cstdio> using namespace std; int N,K,a[17]; long long f[1<<16][17]; inline int abs(int x){return x>0?x:-x;} int main() { scanf("%d%d",&N,&K); register int i,j,k

AC日记——[USACO06FEB]奶牛零食Treats for the Cows 洛谷 P2858

[USACO06FEB]奶牛零食Treats for the Cows 思路: 区间DP: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 2005 #define ll long long ll n,ai[maxn],dp[maxn][maxn],sum[maxn]; inline void in(ll &now) { char Cget=getchar();now=0; while(Cget>'9'

【题解】黑白奶牛

题目描述 有N只奶牛从左往右排成一行,编号是1至N.这N只奶牛当中,有一些奶牛是黑色的,其余的是白色的. color[i]表示第i只奶牛的颜色,如果color[i]=0则表示第i头奶牛是黑色的,如果color[i]=1则表示第i头奶牛是白色的. 六一奶牛儿童节快到了,农场主Farmer John要从这N头奶牛当中,挑选尽可能多的奶牛去参加晚会. Farmer John挑选奶牛的原则是:挑选编号是连续的一段奶牛,这一段奶牛的颜色必须全部是白色的. Farmer John有一个魔法棒,每用一次魔法棒

【题解】幸运奶牛

题目描述 有N头奶牛从左往右排成一行,编号是1至N.如果某头奶牛的编号是2的倍数或者是3的倍数,那么这头奶牛就是幸运奶牛.这N头奶牛中,总共有多少头奶牛是幸运奶牛? 输入输出格式 输入格式 一行,一个整数N. 输出格式 一行,一个整数,表示幸运奶牛的数量. 输入输出样例 输入样例 10 输出样例 7 说明 数据规模 对于70%的数据,1≤N≤10000. 对于100%的数据,1≤N≤2000000000. 题解 小学奥数,直接上代码. #include <cstdio> int main()