1. 程式人生 > >B1231 [Usaco2008 Nov]mixup2 混亂的奶牛 狀壓dp

B1231 [Usaco2008 Nov]mixup2 混亂的奶牛 狀壓dp

typedef turn 能夠 lean putc 方案 64位 發現 inf

發現是狀壓dp,但是還是不會。。。之前都白學了,本蒟蒻怎麽這麽菜,怎麽都學不會啊。。。

其實我位運算基礎太差了,所以狀壓學的不好。

題幹:

Description

混亂的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)頭奶牛中的每一頭都有一個唯一的編號S_i (1 <= S_i <= 25,000). 奶牛為她們的編號感到驕傲, 所以每一頭奶牛都把她的編號刻在一個金牌上, 並且把金牌掛在她們寬大的脖子上.
奶牛們對在擠奶的時候被排成一支"混亂"的隊伍非常反感. 如果一個隊伍裏任意兩頭相鄰的奶牛的編號相差超過K (1 <= K <= 3400
), 它就被稱為是混亂的. 比如說,當N = 6, K = 1時, 1, 3, 5, 2, 6, 4 就是一支"混亂"的隊伍, 但是 1, 3, 6, 5, 2, 4
不是(因為5和6只相差1). 那麽, 有多少種能夠使奶牛排成"混亂"的隊伍的方案呢? Input * 第 1 行: 用空格隔開的兩個整數N和K * 第 2..N+1 行: 第i+1行包含了一個用來表示第i頭奶牛的編號的整數: S_i Output 第 1 行: 只有一個整數, 表示有多少種能夠使奶牛排成"混亂"的隊伍的方案. 答案保證是 一個在64位範圍內的整數. Sample Input 4 1 3
4 2 1 Sample Output 2 輸出解釋: 兩種方法分別是: 3 1 4 2 2 4 1 3 HINT

代碼:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define
duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < 0 || c > 9) if(c == -) op = 1; x = c - 0; while(c = getchar(), c >= 0 && c <= 9) x = x * 10 + c - 0; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar(-), x = -x; if(x >= 10) write(x / 10); putchar(0 + x % 10); } int ms,n, k, a[20]; ll dp[70004][20]; int main() { read(n);read(k); duke(i,1,n) { read(a[i]); dp[1 << (i - 1)][i] = 1; } int ms = (1 << n) - 1; duke(i,1,ms) { duke(j,1,n) { if(i & (1 << (j - 1))) //判斷是否為0 { duke(p,1,n) { if(p != j && (i & (1 << (p - 1))) && abs(a[p] - a[j]) > k) dp[i][j] += dp[i ^ (1 << (j - 1))][p]; } } } } ll ans = 0; duke(i,1,n) { ans += dp[ms][i]; } write(ans); printf("\n"); return 0; }

B1231 [Usaco2008 Nov]mixup2 混亂的奶牛 狀壓dp