zoukankan      html  css  js  c++  java
  • 【POJ 1351】Number of Locks

    Number of Locks
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 1198   Accepted: 589

    Description

    In certain factory a kind of spring locks is manufactured. There are n slots (1 < n < 17, n is a natural number.) for each lock. The height of each slot may be any one of the 4 values in{1,2,3,4}( neglect unit ). Among the slots of a lock there are at least one pair of neighboring slots with their difference of height equal to 3 and also there are at least 3 different height values of the slots for a lock. If a batch of locks is manufactured by taking all over the 4 values for slot height and meet the two limitations above, find the number of the locks produced.

    Input

    There is one given data n (number of slots) on every line. At the end of all the input data is -1, which means the end of input.

    Output

    According to the input data, count the number of locks. Each output occupies one line. Its fore part is a repetition of the input data and then followed by a colon and a space. The last part of it is the number of the locks counted.

    Sample Input

    2
    3
    -1
    

    Sample Output

    2: 0
    3: 8
    

    Source

     
    这是一道统计方案数的题目,就是和组合数学有关的题目,但一直没想到用组合数学怎么做,于是就弃了,用DP。
    DP也比较复杂。
    明显要用一维来记阶段,表示i个槽的方案数。
    但是,仔细想想,前面i-1不符合要求的方案数加了i下去之后是有可能变成合法的方案的!所以,我们不光要记录合法方案数,也需要记录不合法方案数。
    再用一维来记录已经出现数字,其实就是一个集合,我们用二进制压缩,例如,四个数都出现过的集合就是1111(2)。
    延续一般DP的手段,我们还需要记录 i 这位放的数字,再加一维。
    好了,已经三维了,还不能进行DP么?是的,现在还不能,因为题目还有一个条件至少有一对相邻的高度差是3,也就是一定要出现1,4或者4,1这两对数。
    我们再加一维来记录吧。。。用0,1表示即可,0表示没有出现过这种情况,1相反。
    终于可以DP了。。。
    g[n][S][i][01];
    方程也是比较复杂的。
      我们枚举n-1的出现数字的集合,为什么不枚举n的状态呢??答案是可以的,但是这样写会让情况变得复杂。
      加入n-1的集合是S,第n位放的数字是i,第n-1位放的数字是j,由于我们枚举的是n-1的集合,所以,我们要判断集合中有没有j。
        (1)|i-j|=3.
          这种情况是毋庸置疑的,我们并不需要更新g[n][S + i][i][0]的状态。
            g[n][S + i][i][1] += g[n - 1][S][j][0] + g[n - 1][S][j][1];
        (2)除(1)外的情况。
          g[n][S + i][i][0] += g[n - 1][S][j][0]
          g[n][S + i][i][1] += g[n - 1][S][j][1]
    答案就是S集合最少有三个元素的情况相加了。
    最后需要注意的是,g数组要用long long存储。
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    long long g[20][1 << 4][4][2], f[20];
    
    void init()
    {
        memset(g, 0, sizeof(g));
        memset(f, 0, sizeof(f));
        for (int i = 0; i < 4; ++i)
            g[1][1 << i][i][0] = 1;
        for (int n = 2; n <= 17; ++n)
        {
            for (int i = 1; i < (1 << 4); ++i)
            {
                for (int j = 0; j < 4; ++j)
                    for (int k = 0; k < 4; ++k)
                        if (i & (1 << k))
                        {
                            if ((j == 0 && k == 3) || (j == 3 && k == 0))
                                g[n][i | (1 << j)][j][1] += g[n - 1][i][k][0] + g[n - 1][i][k][1];
                            else
                            {
                                g[n][i | (1 << j)][j][0] += g[n - 1][i][k][0];
                                g[n][i | (1 << j)][j][1] += g[n - 1][i][k][1];
                            }
                        }
            }
            for (int i = 0; i < 4; ++i)
            {
                f[n] += g[n][15][i][1];
                for (int j = 0; j < 4; ++j)
                    f[n] += g[n][15 ^ (1 << i)][j][1];
            }
        }
    }
    
    int main()
    {
        init();
        int n;
        while (scanf("%d", &n) == 1 && n != -1)
            cout << n << ": " << f[n] << endl;
        return 0;
    }
  • 相关阅读:
    Mybatis-generator使用和扩展
    mybatis like 查询
    mybatis IF判断的坑
    Spring 配置JNDI数据源
    MyBatis Generator配置文件
    Dynamic Web Module to 3.0 报错
    MAC下配置MAVEN环境变量配置
    ORA-02298: 无法验证 (PNET.POST_CLOB_FK)
    oracle pctfree和pctused详解
    关于error:Cannot assign to 'self' outside of a method in the init family
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4905581.html
Copyright © 2011-2022 走看看