动态规划 计数型DP

令人愉快的单词(dobra)
时间限制: 0.1 秒
空间限制: 32 MB
【问题描述】
Lea 在她的一生中碰到过很多单词。其中的很大一部分都使她不愉快。作为
补偿,她开始创造一些愉快的单词。 Lea 通过写下一些看起来很不错的字母在一
张纸上来创造新单词。接下来,她擦掉一些看起来最令人讨厌的字母,并用‘_‘
来代替它们。接下来,她想要用更令人接受的字母替换掉这些下划线来构成一个
令人愉快的单词。
Lea 认为一个单词是愉快的当且仅当这个单词不包括 3 个连续的元音,不包
括 3 个连续的辅音并且包括至少一个‘L‘。
在克罗地亚文中,属于元音的字母只有 A, E, I, O, U。其它的都是辅音。
【输入文件】
输入文件 dobra.in 只有 1 行,为一个不超过 100 个字符的字符串。这个字符
串只包括大写的英文字母和‘_‘。数据保证输入中的‘_‘不超过 10 个。
【输出文件】
输出文件 dobra.out 包括一个整数,表示通过替换输入中的下划线可以构成
多少个令人愉快的单词。
注意:请使用 64 位整数类型。对于 C/C++语言,请使用 long long,对于 Pascal
语言,请使用 int64
【输入输出样例】
input
L_V
input
V__K
input
JA_BU_K_A
output
5
output
10
output
485

三维数组DP,第一维指枚举到了那位,第二维中

  下标0指连续有一个辅音并没有出现过三元或三辅的情况数

  下标1指连续有两个辅音并没有出现过三元或三辅的情况数

  下标2指连续有一个元音并没有出现过三元或三辅的情况数

  下标4指连续有两个元音并没有出现过三元或三辅的情况数

第三维中指是否出现过‘L’。

看起来复杂其实思路很简单

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 using namespace std;
  5 char s[110];
  6 long long dp[110][7][2];
  7 bool ISyuan(char c)
  8 {return c==‘A‘||c==‘E‘||c==‘I‘||c==‘O‘||c==‘U‘;}
  9
 10 int main()
 11 {
 12     freopen("dobra.in","r",stdin);
 13     freopen("dobra.out","w",stdout);
 14     scanf("%s",s+1);
 15     s[0]=‘1‘;
 16     int len=strlen(s)-1,tot=0;
 17     for(int i=1;i<=len;i++)
 18     {
 19         if(s[i]==‘_‘){
 20             tot++;
 21         }
 22         else{
 23             if(s[i-1]<=‘Z‘&&s[i-1]>=‘A‘)
 24                 if(s[i+1]<=‘Z‘&&s[i+1]>=‘A‘)
 25                     if(ISyuan(s[i-1])==ISyuan(s[i])&&ISyuan(s[i])==ISyuan(s[i+1])){
 26                         printf("0\n");
 27                         return 0;
 28                     }
 29         }
 30     }
 31     long long total=1;
 32     for(;tot--;)total*=26ll;
 33
 34     if(ISyuan(s[1])){
 35         dp[1][2][0]=1ll;
 36     }
 37     else{
 38         if(s[1]==‘L‘)
 39             dp[1][0][1]=1ll;
 40         else if(s[1]!=‘_‘)
 41             dp[1][0][0]=1ll;
 42         else{
 43             dp[1][0][0]=20;
 44             dp[1][0][1]=1;
 45             dp[1][2][0]=5;
 46         }
 47     }
 48
 49     for(int i=2;i<=len;i++)
 50     {
 51         if(s[i]==‘_‘){
 52             dp[i][4][0]=dp[i-1][4][0]*25ll;
 53             dp[i][4][1]=dp[i-1][4][0]+dp[i-1][4][1]*26ll;
 54
 55             dp[i][4][0]+=dp[i-1][1][0]*20ll;
 56             dp[i][4][1]+=dp[i-1][1][1]*21ll+dp[i-1][1][0];
 57             dp[i][4][0]+=dp[i-1][3][0]*5ll;
 58             dp[i][4][1]+=dp[i-1][3][1]*5ll;
 59
 60             dp[i][0][0]=dp[i-1][2][0]*20ll+dp[i-1][3][0]*20ll;
 61             dp[i][0][1]=(dp[i-1][2][1]+dp[i-1][3][1])*21ll+dp[i-1][2][0]+dp[i-1][3][0];
 62
 63             dp[i][1][0]=dp[i-1][0][0]*20ll;
 64             dp[i][1][1]=dp[i-1][0][1]*21ll+dp[i-1][0][0];
 65
 66             dp[i][2][0]=dp[i-1][0][0]*5ll+dp[i-1][1][0]*5ll;
 67             dp[i][2][1]=dp[i-1][0][1]*5ll+dp[i-1][1][1]*5ll;
 68
 69             dp[i][3][0]=dp[i-1][2][0]*5ll;
 70             dp[i][3][1]=dp[i-1][2][1]*5ll;
 71         }
 72
 73         else{
 74             if(ISyuan(s[i])){
 75                 dp[i][0][0]=dp[i][0][1]=dp[i][1][0]=dp[i][1][1]=0ll;
 76
 77                 dp[i][2][0]=dp[i-1][0][0]+dp[i-1][1][0];
 78                 dp[i][2][1]=dp[i-1][0][1]+dp[i-1][1][1];
 79
 80                 dp[i][3][0]=dp[i-1][2][0];
 81                 dp[i][3][1]=dp[i-1][2][1];
 82
 83                 dp[i][4][0]=dp[i-1][4][0]+dp[i-1][3][0];
 84                 dp[i][4][1]=dp[i-1][4][1]+dp[i-1][3][1];
 85             }
 86             else{
 87                 dp[i][2][0]=dp[i][2][1]=dp[i][3][0]=dp[i][3][1]=0ll;
 88                 if(s[i]==‘L‘){
 89                     dp[i][0][0]=dp[i][1][0]=dp[i][2][0]=dp[i][3][0]=dp[i][4][0]=0ll;
 90
 91                     dp[i][0][1]=dp[i-1][2][0]+dp[i-1][2][1]+dp[i-1][3][0]+dp[i-1][3][1];
 92                     dp[i][1][1]=dp[i-1][0][0]+dp[i-1][0][1];
 93
 94                     dp[i][4][1]=dp[i-1][4][0]+dp[i-1][4][1];
 95                     dp[i][4][1]+=dp[i-1][1][0]+dp[i-1][1][1];
 96                 }
 97                 else{
 98                     dp[i][4][0]=dp[i-1][4][0]+dp[i-1][1][0];
 99                     dp[i][4][1]=dp[i-1][4][1]+dp[i-1][1][1];
100
101                     dp[i][0][0]=dp[i-1][2][0]+dp[i-1][3][0];
102                     dp[i][0][1]=dp[i-1][2][1]+dp[i-1][3][1];
103
104                     dp[i][1][0]=dp[i-1][0][0];
105                     dp[i][1][1]=dp[i-1][0][1];
106                 }
107             }
108         }
109     }
110     long long off=dp[len][4][0]+dp[len][4][1]+dp[len][0][0]+dp[len][1][0]+dp[len][2][0]+dp[len][3][0];
111     printf("%lld\n",total-off);
112     return 0;
113 }
时间: 2024-08-26 19:08:43

动态规划 计数型DP的相关文章

动态规划 树型DP

codves5565 二叉苹果树 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1.我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果.       给定需要保留的树枝数量,求出最多能留住多少苹果. 输入描述 Input Description 第1行2

0x50 动态规划(0x5C 计数类DP)例题3:装饰围栏(题解)(计数类DP讲解,确定第k个排列)

计数类DP一般就是确定DP状态,DP出排名范围,然后不断逼近. 题意 题目链接 [题目描述] 有 N 块长方形的木板,长度分别为1,2,-,N,宽度都是1. 现在要用这 N 块木板组成一个宽度为 N 的围栏,满足在围栏中,每块木板两侧的木板要么都比它高,要么都比它低. 也就是说,围栏中的木板是高低交错的. 我们称"两侧比它低的木板"处于高位,"两侧比它高的木板"处于低位. 显然,有很多种构建围栏的方案. 每个方案可以写作一个长度为N的序列,序列中的各元素是木板的长度

区间型DP

区间型DP是一类经典的动态规划问题,主要特征是可以先将大区间拆分成小区间求解最后由小区间的解得到大区间的解. 有三道例题 一.石子合并 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 二.能量项链 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个

采药---0-1背包型dp

题目描述 Description 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:"孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值.我会给你一段时间,在这段时间里,你可以采到一些草药.如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大." 如果你是辰辰,你能完成这个任务吗? 输入描述 Input Descriptio

HDU1561 The more, The Better(树型DP)

题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值 但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度! 看了题解,原来这是依赖背包,没看背包九讲..不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示: dp[u][

POJ3659 Cell Phone Network(树上最小支配集:树型DP)

题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. 树上的每个结点作为其子树的根可以有三个状态: 不属于支配集且还没被支配 不属于支配集但被其孩子支配 属于支配集 那么就是用dp[u][1\2\3]来表示动归的状态. 123转移该怎么转移就怎么转移..最后的结果就是min(dp[root][2],dp[root][3]). 要注意的是对于有些结点前2

HDU_1561_The more, The Better_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7031    Accepted Submission(s): 4121 Problem Description ACboy很喜欢玩一种战略游戏,

HDU_1520_Anniversary party_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8233    Accepted Submission(s): 3574 Problem Description There is going to b

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=