zoukankan      html  css  js  c++  java
  • Black and White

    Black and White

    题目链接:http://www.ifrog.cc/acm/problem/1091?contest=1012&no=0

    DP

    按照常规想法会这样定义状态:dp[当前位数i][当前位是否为黑][连续棋子的个数k]为符合状态的方案数,

    但是题目中a,b,n均为1e6,不论空间还是时间都不允许这样做,考虑另外的状态定义:

      dp[当前位数i][当前位是否为黑]表示符合状态的合法的方案数;

    当前位数大于最大连续棋子数(a,b)时,dp[i][1]=dp[i-1][1]+dp[i-1][0]中包含了连续a个黑棋的非法状态,

    而连续a个黑棋的非法状态数与dp[i-a][0]相同(第i-a位到第i位只有均为黑一种情况),将其删去即为合法状态;白棋亦然。

    于是状态转移方程为:

    • 当i<a&&i<b(从下标1开始)时,
      • dp[i][1]=dp[i-1][1]+dp[i-1][0];
      • dp[i][0]=dp[i-1][1]+dp[i-1][0];
    • 当i>=a||i>=b时,
      • dp[i][1]=dp[i-1][1]+dp[i-1][0];
      • dp[i][0]=dp[i-1][1]+dp[i-1][0];
      • dp[i][1]=dp[i][1]-dp[i-a][0];
      • dp[i][0]=dp[i][0]-dp[i-b][1];

    代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <string>
     6 #define N 1000005
     7 using namespace std;
     8 typedef long long ll;
     9 ll m=1e9+7;
    10 ll T,a,b,n,dp[N][2];
    11 int main(void){
    12     std::ios::sync_with_stdio(false);
    13     dp[0][1]=dp[0][0]=dp[1][1]=dp[1][0]=1;
    14     cin>>T;
    15     while(T--){
    16         cin>>a>>b>>n;
    17         for(int i=2;i<=n;++i){
    18             dp[i][1]=(dp[i-1][1]+dp[i-1][0])%m;
    19             dp[i][0]=(dp[i-1][1]+dp[i-1][0])%m;
    20             if(i>=a)dp[i][1]=(dp[i][1]-dp[i-a][0]+m)%m;
    21             if(i>=b)dp[i][0]=(dp[i][0]-dp[i-b][1]+m)%m;
    22         }
    23         cout<<(dp[n][0]+dp[n][1])%m<<"
    ";
    24     }
    25 }
  • 相关阅读:
    002-mybatis主配置文件
    001-mybatis框架
    mybatis学习
    tcp连接与释放
    浏览器输入url的全过程
    设备
    读写分离(三)
    读写分离(二)
    读写分离(一)
    主从复制(三)
  • 原文地址:https://www.cnblogs.com/barrier/p/6415990.html
Copyright © 2011-2022 走看看