zoukankan      html  css  js  c++  java
  • HDU 5642 King's Order dp

    题目链接:

     http://acm.hdu.edu.cn/showproblem.php?pid=5642

    King's Order

     
     Accepts: 381
     
     Submissions: 1361
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    国王演讲后士气大增,但此时战争还没有结束,国王时不时要下发命令。 由于国王的口吃并没有治愈,所以传令中可能出现:“让第三军-军-军,到前线去” 这样的命令。由于大洋国在军队中安插了间谍 , 战事紧急,很多时候前线的指挥官不能分清哪些命令真正来自国王。但国王的命令有一个特点,他每次连续重复的字符最多 3 次. 所以说他的命令中没有:“让第三军-军-军-军 , 到前线去”,但是可以有 :“让第三军-军 , 到前线去” 。 此时将军找到了你,你需要告诉他,给定命令的长度长度为 n,有多少种不同的命令可以是国王发出的 。(也就是求长度为 n 的合格字符串的个数)当然,国王可能说出一句话没有犯任何口吃,就像他那次演讲一样。 为了简化答案,国王的命令中只含有小写英文字母,且对答案输出模 1000000007。 我们认为两个命令如果完全相同那么这两个字符串逐个比较就完全相同。
    输入描述
    第一行一个整数表示测试组数:T(T le10)。 每组数据占一行,每行一个正整数 n(n le 2000) 表示字符串的长度。
    输出描述
    T 行,每行一个整数表示合法的命令数量。
    输入样例
    2 2 4
    输出样例
    676 456950
    Hint
    两个中没有不符合要求的,所以答案为 26	imes 26 = 676 四个不符合要求的只有 `aaaa` `bbbb` ... `zzzz`总共 26 个 那么答案就是: 26^4-26 = 456950

    题解: 

    方法一: 

    dp[i][j]表示长度为i以字母j+'a'结尾的所有合法情况,现在我们先考虑所有情况再减去那些非法情况(以连续四个j结尾的状态为非法状态 ,超过四个j的之前一定已经考虑过了,这里不能再考虑进去)所以先预处理出i<=4的值,对于i>5,有如下转移方程:

    dp[i][j]=∑dp[i-1][k]-( ∑dp[i-4][k](k!=j) )
     代码1:

      1 #include<iostream>

     2 #include<cstdio>
     3 #include<cstring> 
     4 typedef long long LL;
     5 using namespace std;
     6 
     7 
     8 const int maxn=2000+10;
     9 const int mod=1e9+7;
    10 
    11 int dp[maxn][33];
    12 int n;
    13 
    14 void init(){
    15     memset(dp,0,sizeof(dp));
    16 }
    17 
    18 int main(){
    19     int tc;
    20     scanf("%d",&tc);
    21     while(tc--){
    22         init();
    23         scanf("%d",&n);
    24         for(int j=0;j<26;j++) dp[1][j]=1;
    25         for(int i=2;i<=n;i++){
    26             int sum=0;
    27             for(int j=0;j<26;j++){
    28                 sum+=dp[i-1][j];
    29                 sum%=mod;
    30             }
    31             for(int j=0;j<26;j++){
    32                 dp[i][j]=sum;
    33                 if(i==4){
    34                     dp[i][j]=(dp[i][j]-dp[i-3][j]+mod)%mod;
    35                 }
    36                 else if(i>4){
    37                     //tmp记录连续四个j结尾的情况。 
    38                     int tmp=0;
    39                     for(int k=0;k<26;k++){
    40                         if(k==j) continue;
    41                         tmp+=dp[i-4][k];
    42                         tmp%=mod;
    43                     }
    44                     dp[i][j]=(dp[i][j]-tmp+mod)%mod;
    45                 }
    46             }
    47         }
    48         int ans=0;
    49         for(int i=0;i<26;i++) {
    50             ans+=dp[n][i];
    51             ans%=mod;
    52         }
    53         printf("%d ",ans);
    54     }
    55     return 0;
    56 }

     

    View Code 

  • 相关阅读:
    Win8系统 Python安装
    一些安卓开源框架整理
    Android 媒体键监听以及模拟媒体键盘的实现 demo
    android View 自动 GONE 问题
    Android 定时器TimerTask 简单使用
    关于Android studio 相对 eclipse 优点
    Java序列化与反序列化
    android shape的使用 边框
    Android Studio 修改 包名 package name
    Android WebView Long Press长按保存图片到手机
  • 原文地址:https://www.cnblogs.com/fenice/p/5284507.html
Copyright © 2011-2022 走看看