zoukankan      html  css  js  c++  java
  • 状压DP [Usaco2008 Nov]mixup2 混乱的奶牛

    本人水平有限,题解不到为处,请多多谅解

    本蒟蒻谢谢大家观看

    题目:

    Problem H: [Usaco2008 Nov]mixup2 混乱的奶牛

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 109  Solved: 59
    [Submit][Status][Web Board]

    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

    转移法类似于floyd,枚举中转点  f[i][j]=f[i][k]+f[k][j];只不过状压DP 是由上一个状态转移而来,再统计总和,即:f[i][j]=f[i][j]+f[上一个状态][k];

    其中的方法转移详解请看另一题:https://www.cnblogs.com/nlyzl/p/11281593.html

    code:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    long long f[1<<17][17];
    //f[i][j]表示【第i个位置的状态】【最后一头奶牛为j】的方案数 
    int s[20];
    long long ans=0;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&s[i]);
        for(int i=1;i<=n;i++)
        //10000 ……1 
        //1000  ……1 
        //100   ……1 
        //10    ……1 
            f[1<<(i-1)][i]=1;//    当只取一头奶牛时,初始为 1;
        
        for(int i=1;i<=(1<<n)-1;i++)     
             //1111
             //10000-1==1111 所以为2的n次方-1  ==   1左移n位-1 
            for(int j=1;j<=n;j++)
                if(i&(1<<(j-1)))
                    for(int k=1;k<=n;k++)
                        if(j!=k&&i&(1<<(k-1))&&abs(s[j]-s[k])>m)
        //依据题意:差值要大于m,且保证第k头奶牛选并且第j头奶牛也选,且j!=k。 
                            f[i][j]+=f[i^(1<<(j-1))][k];
        //当前状态的方案数  == 上一个状态的方案数累加而成 
        for(int i=1;i<=n;i++)
            ans+=f[(1<<n)-1][i];
    //全取时为(1111),此时 任何一头奶牛都可以为结尾,再来用ans统计方案数的和 
        printf("%lld
    ",ans);
     } 
  • 相关阅读:
    c# System.Object类和数据的安全转型
    计算机内存的组织方式
    c# ref和out参数
    C# 复制值类型的变量和类
    PCB 布线,直角线,差分线,蛇形线
    c# 静态方法和数据
    c# 类的知识
    appium中从activity切换到html
    No Desktop License Servers available to provide a license
    adb命令连接Android模拟器夜神模拟器
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11297198.html
Copyright © 2011-2022 走看看