• FZUOJ Problem 2200 cleaning DP


    Problem 2200 cleaning

     

     Problem Description

    N个人围成一圈在讨论大扫除的事情,需要选出K个人。但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法。

     Input

    第一行包含一个数T(T<=100),表示测试数据的个数。

    接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N)。

     Output

    输出满足题意的方案数,方案数很大,所以请输出方案数mod 1,000,000,007 后的结果。

     Sample Input

    2 4 2 8 3

     Sample Output

    4 16

     Source

    FOJ有奖月赛-2015年10月
     
     
    题解:
      设定 f[k][h] [i][j] 表示在不考虑环的清形下第一,二位置上的选择状态为k,h下,前i个选了j个人的方案数
        dp[k][h][i][j], 表示在考虑环的清形下第一,二位置上的选择状态为k,h下,前i个选了j个人的方案数
      那么对于f数组的递推,当前第i位置选与不选,i-1位置选与不选有
            f[k][h] = f[k][h][ii-1][j] +f[k][h][i-3][j-1] + f[k][h][i-4][j-2];
      对于dp数组转移同理就是拿f数组来更新
      具体看代码
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    typedef unsigned long long ULL;
    const long long INF = 1e18+1LL;
    const double pi = acos(-1.0);
    const int N = 1e3+20, M = 1e6+10, mod = 1e9+7,inf = 2e9;
    
    void update(int x,int& y) {
        y += x;
        if(y > mod) y -= mod;
    }
    int T,dp[2][2][N][N],f[2][2][N][N];//前i个人选j人,前两人状态
    void init() {
        dp[0][0][0][0] = 1;
        dp[0][0][1][0] = 1;
        dp[1][0][1][1] = 1;
        dp[0][0][2][0] = 1;
        dp[1][0][2][1] = 1;
        dp[0][1][2][1] = 1;
        dp[1][1][2][2] = 1;
    
        dp[0][0][3][0] = 1;
    
        dp[0][0][3][1] = 1;
        dp[0][1][3][1] = 1;
        dp[1][0][3][1] = 1;
    
        dp[1][1][3][2] = 1;
        dp[1][0][3][2] = 1;
        dp[0][1][3][2] = 1;
    
        dp[1][1][3][3] = 1;
    
    
    
    
    
        for(int i = 0; i < 2; ++i) {
            for(int j = 0; j < 2; ++j) {
                for(int k = 0; k <= 3; ++k) {
                    for(int h = 0; h <= k; ++h)
                        f[i][j][k][h] = dp[i][j][k][h];
                }
            }
        }
        f[1][1][3][3] = 0;
        f[1][0][3][2] = 0;
        for(int k = 0; k < 2; ++k) {
            for(int h = 0; h < 2; ++h) {
                for(int i = 4; i <= 1000; ++i) {
                    for(int j = 0; j <= i; ++j) {
                    //不选, i-1选
                    if(i >= 5) {
                        if(!k && j >= 1) update(f[k][h][i-4][j-1],dp[k][h][i][j]);
                     if(!k && j >= 2)
                        if(i >= 5)update(f[k][h][i-5][j-2],dp[k][h][i][j]);
                    }
                    else {
                         if(!k && j >= 1) update(f[k][h][i-2][j-1],dp[k][h][i][j]);
                    }
    
                    //i不选,i-1不选
                    update(f[k][h][i-2][j],dp[k][h][i][j]);
                    //i位置选,i-1不选
                    if(!h&&j>=1)update(f[k][h][i-3][j-1],dp[k][h][i][j]);
    
    
                     //i位置选,i-1选
                     if(!k&&!h&&j>=2)
                        update(f[k][h][i-4][j-2],dp[k][h][i][j]);
    
                     update(f[k][h][i-1][j],f[k][h][i][j]);
                     if(i>=3&&j>=1)update(f[k][h][i-3][j-1],f[k][h][i][j]);
                     if(i>=4&&j>=2)update(f[k][h][i-4][j-2],f[k][h][i][j]);
                    }
                }
            }
        }
    }
    int main() {
        init();
        scanf("%d",&T);
        while(T--) {
            int k,n;
            scanf("%d%d",&n,&k);
            int ans = 0;
            for(int i = 0; i < 2; ++i) {
                for(int j = 0; j < 2; ++j) {
                    update(dp[i][j][n][k],ans);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    mysql问题: alter导致速度慢
    MySQL的mysql_insert_id和LAST_INSERT_ID
    linux动态链接库---一篇讲尽
    jsoncpp第二篇------API
    SVN第二篇-----命令集合
    svn第一篇----入门指南
    数据结构之堆
    SZU4
    SZU1
    SZU2
  • 原文地址:https://www.cnblogs.com/zxhl/p/7259040.html
Copyright © 2020-2023  润新知