【状压DP】【cofun1040】混乱奶牛

来源:互联网 发布:台湾人用淘宝吗 编辑:程序博客网 时间:2024/05/19 03:45

【cofun1040】混乱奶牛

Description
约翰家有N头奶牛,第i头奶牛的编号是Si,每头奶牛的编号都是唯一的。这些奶牛最近在闹脾气,为表达不满的情绪,她们在挤奶的时候一定要排成混乱的队伍。在一只混乱的队伍中,相邻奶牛的编号之差均超过K。
比如当K = 2时,1, 3, 5, 2, 6, 4就是一支混乱的队伍,而1, 3, 6, 5, 2, 4不是,因为6和5只差1。请数一数,有多少种队形是混乱的呢?

Input Format
第一行:两个用空格分开的整数: N和K,4 ≤ N ≤ 16,1 ≤ K ≤ 3400
第二行到N + 1行:第i + 1行包括一个整数Si,1 ≤ Si ≤ 25000
Output Format
第一行:一个整数,表示混乱队伍的数量,保证答案小于263

Sample Input
4 1
3
4
2
1
Sample Output
2

Hint
两个满足条件的排法是3,1,4,2和2,4,1,3

Source
USACO 2008 Nov


  • 分析:
    • n <= 16,且状态(排队的奶牛)相关联,考虑状压DP。
      转移方程:
f[i | (1 << l)][l] += f[i][j];

f[i][j]:状态为i(0:未排队/ 1:排队)时队伍最后是第j头奶牛的情况种数。
【想到是状压后就蛮裸了。


  • 代码:
#include <bits/stdc++.h> using namespace std; int n, k, s[20], i, j, l; long long ans, f[1 << 16][16]; int main() {    scanf("%d%d", &n, &k);    for(i = 0; i < n; i ++) scanf("%d", &s[i]);    //读入     for(i = 0; i < n; i ++) f[1 << i][i] = 1;    for(i = 1; i < (1 << n); i ++)        for(j = 0; j < n && (1 << j) <= i; j ++)        if ((1 << j) & i)            for(l = 0; l < n; l ++)            if (! ((1 << l) & i))                if (fabs(s[l] - s[j]) > k)                    f[i | (1 << l)][l] += f[i][j];    //状压DP     for(ans = i = 0; i < n; i ++)        ans += f[(1 << n) - 1][i];    printf("%lld", ans);    //统计并输出     return 0; }

满月已霜—Midaho妹纸的翻唱巨美~

阅读全文
0 0
原创粉丝点击