洛谷 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 namespace std;
 5
 6 typedef long long llt;
 7 const int maxn=16;
 8 int n,k;
 9 //每只奶牛的高度
10 int a[maxn];
11 //记忆化数组
12 llt dp[maxn][1<<maxn];
13
14 void init() {
15     scanf("%d%d",&n,&k);
16     for (int i=0;i<n;i++)
17         scanf("%d",a+i);
18     //因为可能搜索完答案是0,所以说要初始化成-1
19     memset(dp,-1,sizeof(dp));
20 }
21
22 //搜索以x号奶牛为队尾,状态为S时可以有多少种情况
23 llt dfs(int x, int S) {
24     //如果全部奶牛都能放进来,且构成了一个混乱队形,则有一种情况
25     if (S==(1<<n)-1) return 1;
26     //记忆化
27     if (dp[x][S]!=-1) return dp[x][S];
28     llt res=0;
29     for (int i=0;i<n;i++) {
30         //判断是否符合情况
31         if (S&(1<<i)) continue;
32         if (abs(a[x]-a[i])<=k) continue;
33         //继续搜索
34         res+=dfs(i,S|(1<<i));
35     }
36     return dp[x][S]=res;
37 }
38
39 int main() {
40     init();
41     llt ans=0;
42     //每种奶牛都当一次队头
43     for (int i=0;i<n;i++)
44         ans+=dfs(i,1<<i);
45     printf("%lld\n",ans);
46     return 0;
47 }

原文地址:https://www.cnblogs.com/tweetuzki/p/8168831.html

时间: 2024-10-18 07:39: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

题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题目链接 数据规模16-20的都是状压 如果要每一位都压序号的话空间肯定是不够的,所以每一位只能是0或1.1表示有这头牛,0表示没有这头牛.显然每个位置的选择和他两边的牛有关,所以我们就可以定义这样的状态: f[i][j]表示使用集合i的牛,其中最后一头牛的序号为j时的总方案数.答案从f[(1 << n) - 1][n]累加即可. 转移也比较好想,从i中枚举选出倒数第二头牛,作为子状态的最后一头牛,注意边界情况.

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>

[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

洛谷 P2858 [USACO06FEB]奶牛零食Treats for the Cows

题目描述 FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per day and wants to maximize the money he receives over a given period time. The treats are interesting for many re

洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm

P2919 [USACO08NOV]守护农场Guarding the Farm 题目描述 The farm has many hills upon which Farmer John would like to place guards to ensure the safety of his valuable milk-cows. He wonders how many guards he will need if he wishes to put one on top of each hill

洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk

题目描述 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要.帮助Marry乳业找到最优的牛奶采购方案. Marry乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是不同的.此外,就像每头奶牛每天只能挤出固定数量的奶,每位奶农每天能提供的牛奶数量是一定的.每天Marry乳业可以从奶农手中采购到小于或者等于奶农最大产量的整数数量的牛奶. 给出Marry乳业每天对牛奶的需求量,还有每位奶农提供的牛奶单价和产量.计算采购足够数量的牛奶所需的最小花费. 注:每天所有奶农