zoukankan      html  css  js  c++  java
  • Codeforces 1105C Ayoub and Lost Array (计数DP)

    <题目链接>

    题目大意:

    有一个长度为 n 的数列的未知数列,数列的每一个数的值都在区间 [l,r]  的范围内。现在问你能够构成多少个这样的数组,使得数组内的所有数的和能够被 3 整除。

    解题分析:

    类似于这种数据量大的计数问题,要不就是数学推公式,要不就是dp。     

    根据所有数之和能被3整除的性质,我们将所有数用%3的余数表示,推出状态转移方程:$$ dp[i][j+k]=dp[i-1][j]*num[k]  $$

    $dp[i][j]$表示:前$i$项之和余$j$的方案数。

    这篇博客讲解的比较详细  >>>

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define N int(2e5+7)
    const int mod = 1e9+7;
    ll dp[N][3];
    
    int main(){
        int n,l,r;
        scanf("%d%d%d",&n,&l,&r);
        int num0,num1,num2;     //得到余数分别为0,1,2的数的个数 
        num0=r/3-(l-1)/3; 
        num1=(r-1+3)/3-(l-2+3)/3;
        num2=r-l+1-num0-num1;
        dp[1][0]=num0;      //初始化dp第一项 
        dp[1][1]=num1;
        dp[1][2]=num2;
        for(int i=2;i<=n;i++){
            dp[i][0]=((dp[i-1][0]*num0)%mod+(dp[i-1][2]*num1)%mod+(dp[i-1][1]*num2)%mod)%mod;
            dp[i][1]=((dp[i-1][1]*num0)%mod+(dp[i-1][0]*num1)%mod+(dp[i-1][2]*num2)%mod)%mod;
            dp[i][2]=((dp[i-1][2]*num0)%mod+(dp[i-1][1]*num1)%mod+(dp[i-1][0]*num2)%mod)%mod;
        }
        printf("%d
    ",dp[n][0]);
    }

    2019-02-22

  • 相关阅读:
    POJ 2773 Happy 2006------欧几里得 or 欧拉函数。
    Candies
    subway(dijkstra以最短时间代替最短路)
    昂贵的聘礼
    LightOJ 1074
    SPFA以及各种优化
    Making Huge Palindromes (Manacher)
    Making Huge Palindromes (KMP处理回文串)
    AC自动机基础
    扩展KMP
  • 原文地址:https://www.cnblogs.com/00isok/p/10421356.html
Copyright © 2011-2022 走看看