zoj 3747 dp递推

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170

题解链接:https://blog.csdn.net/papapa_swust/article/details/77745984

代码:

#include <bits/stdc++.h>
#define MAX 1000000+100
#define MOD 1000000007
using namespace std;
/*
zoj 3747  dp 递推 
 
*/
typedef long long ll;
int n,m,k; 
ll dp[MAX][3];//dp[i][0]:表示第 i 个位置 放 0 (G士兵) 的方法数目,一直放满 N 个位置 


ll solve(int u,int v)
{
  //初始化
  dp[0][0] = dp[0][1] = 0;
  dp[0][2] = 1;
  ll sum = 0;
  for (int i=1;i<=n;++i)
   {
        sum = ( dp[i-1][0] + dp[i-1][1] + dp[i-1][2] )%MOD;
        dp[i][2] = sum;
        // 对于G士兵 
        if ( i <= u)
          dp[i][0] = sum;
        else if ( i == u +1) dp[i][0] = sum-1;
        else dp[i][0] = (sum - dp[i-u-1][1] - dp[i-u-1][2] ) % MOD;
        //对于R士兵
      if ( i <= v)
          dp[i][1] = sum;
        else if ( i == v +1) dp[i][1] = sum-1;
        else dp[i][1] = ( sum - dp[i-v-1][0] - dp[i-v-1][2] ) % MOD;
   } 
   return  ( ( dp[n][0] + dp[n][1] + dp[n][2] ) % MOD ); 
}


int main ()
{
  while(~scanf("%d%d%d",&n,&m,&k))
  {
    ll ans = solve(n,k);
    cout << ( ( (ans - solve(m-1,k))%MOD +MOD ) % MOD) << endl;
  }
  
  return 0;
} 
原文地址:https://www.cnblogs.com/yuluoluo/p/8833814.html