zoukankan      html  css  js  c++  java
  • 【题解】Luogu2915 [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 ample bovine neck.

    Gangsta cows are rebellious and line up to be milked in an order called ‘Mixed Up’. A cow order is ‘Mixed Up’ if the sequence of serial numbers formed by their milking line is such that the serial numbers of every pair of consecutive cows in line differs by more than K (1 <= K <= 3400). For example, if N = 6 and K = 1 then 1, 3, 5, 2, 6, 4 is a ‘Mixed Up’ lineup but 1, 3, 6, 5, 2, 4 is not (since the consecutive numbers 5 and 6 differ by 1).

    How many different ways can N cows be Mixed Up?

    For your first 10 submissions, you will be provided with the results of running your program on a part of the actual test data.

    POINTS: 200

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

    输入输出格式

    输入格式:

    • Line 1: Two space-separated integers: N and K

    • Lines 2..N+1: Line i+1 contains a single integer that is the serial number of cow i: S_i

    输出格式:

    • Line 1: A single integer that is the number of ways that N cows can be ‘Mixed Up’. The answer is guaranteed to fit in a 64 bit integer.

    输入输出样例

    输入样例#1: 复制

    4 1 
    3 
    4 
    2 
    1
    

    输出样例#1: 复制

    2
    

    说明

    The 2 possible Mixed Up arrangements are:

    3 1 4 2

    2 4 1 3

    思路

    • 用二进制表示牛的状态state
    • 设$f[state][last]$ 表示牛的排列状态为state,最后一头牛为last时的合法队列数
      • 当且仅当状态j中没有包括第i只牛,且$abs(s[i]-s[last]) > k$ 时,第i只牛可以加入队列中
      • 此时可以有转移方程$dp[State|(1<<i)][i]+=dp[State][last]$

    注意 边界条件为 $dp[i][1<<i]=1$

    • 最终答案
      $$answer= sum_{i=0}^{n-1}dp[(1<<n)-1][i]$$

    代码

    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register int
    #define ll long long
    using namespace std;
    inline int read(){
    	int x=0,w=1;
    	char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    	if(ch=='-') w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    	return x*w;
    }
    const int maxs=(1<<16)+5,maxn=16+5;
    int n,k;
    ll ans;
    ll dp[maxs][maxn],num[maxn];
    int main() {
        n=read(),k=read();
        for(re i=0;i<n;++i) num[i]=read(),dp[1<<i][i]=1;
        for(re S=0;S<(1<<n);++S) for(re i=0;i<n;++i)        //枚举每一个状态
        	if(S&(1<<i)) for(re j=0;j<n;++j)                //第j只牛是否在状态i中,进一步枚举没有在状态i中的牛
        		if(!(S&(1<<j))&&abs(num[j]-num[i])>k)       //如果k不在队列中且差值大于k 
        			dp[S|(1<<j)][j]+=dp[S][i];
    	for(re i=0;i<n;++i) ans+=dp[(1<<n)-1][i];
        printf("%lld
    ",ans);
    	return 0;
    }
    
     
  • 相关阅读:
    IDEA手动创建JFinal项目(404问题处理)
    php 把数字1-1亿换成汉字表述,例如 150 转成 一百五十
    模仿console自写函数打印js的对象
    每瓶啤酒2元,2个空酒瓶或4个瓶盖可换1瓶啤酒。10元最多可喝多少瓶啤酒? php
    js-Event构造函数,也许你需要
    js将金额专成每隔3位数加逗号
    js-PC版监听键盘大小写事件
    用php脚本给html中引用的js和css路径打上版本
    通过js的console优雅的将php调试信息输出
    android中加载的html获取的宽高不正确
  • 原文地址:https://www.cnblogs.com/bbqub/p/8920505.html
Copyright © 2011-2022 走看看