简单dp

Posted lipu123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单dp相关的知识,希望对你有一定的参考价值。

2019级新生小赵终于开始了大学生活,对于未知的大学生活和未来,小赵有着坚定的信心去迎接。

刚开学,小赵就被程序设计竞赛吸引了,觉得能学习知识并且打比赛真好啊,打程序设计竞赛真好玩。为了庆祝自己能了解到程序设计竞赛并且告诫自己在竞赛路上永不言弃,小赵决定把2019作为自己的幸运数字。

一天,小赵遇到一个只含有2,0,1,9四种字符的字符串,他想知道里面有多少个2019,自己能得多少个不同的2019。只要有一个位置不同就算一个新的2019,如,20199就有2个2019,9012有0个2019。

    小赵开心的把今天的事告诉小静,小静听完问:“程序竞赛更好玩吗?”小赵回答:“它不是好不好玩的问题,他是……算了,我把这道题明天讲给你听,你就知道好不好玩了。”小赵为了证明打程序设计竞赛好玩,他找到了你,希望你能做出这道题,看看小赵能得到几个2019,因为结果可能很大,所以结果请对1e9+7进行取模。

输入

本题有多组测试数据,处理到文件结束。

       每组数据占一行,一个由2,0,1,9四种数字组成的字符串,长度小于100000。

输出

        每组数据输出一行,一个整数。

样例输入 Copy

2019119
220109

样例输出 Copy

4
2

解题思路:
简单dp:四个状态转移递推,简单状态转移。
字符串从左向右扫一遍就可以计算得出,类似动态规划
四个变量分别计算2,20,201,2019的数量
遇到0那么20的数量就增加当前2的数量
遇到1那么201的数量就增加当前20的数量
遇到9那么2019的数量就增加当前201的数量

AC代码:
技术图片
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
inline int read() {int x=0,f=1;char c=getchar();while(c!=-&&(c<0||c>9))c=getchar();if(c==-)f=-1,c=getchar();while(c>=0&&c<=9)x=x*10+c-0,c=getchar();return f*x;}
typedef long long ll;
const int maxn = 1e7+10;
const ll N=1e9+7;
char a[maxn];
int main()
{
    while(~scanf("%s",a)){
        int z=0,b=0,c=0,d=0;
        int t=strlen(a);
        for(int i=0;i<t;i++){
            if(a[i]==2){
                z=(z+1)%N;
            }
            if(a[i]==0){
                b=(b+z)%N;
            }
            if(a[i]==1){
                c=(c+b)%N; 
            }
            if(a[i]==9){
                d=(d+c)%N;
            } 
        }
        printf("%d
",d%N);
    }
    return 0;
}
View Code

 

例题2:

链接:https://ac.nowcoder.com/acm/contest/1877/S
来源:牛客网
在庆祝祖国母亲70华诞之际,老师给小乐乐出了一个问题。大家都知道China的英文缩写是CHN,那么给你一个字符串s,你需要做的是统计s中子串“CHN”的个数。      
子串的定义:存在任意下标a < b < c,那么“s[a]s[b]s[c]”就构成s的一个子串。如“ABC”的子串有“A”、“B”、“C”、“AB”、“AC”、“BC”、“ABC”。       
输入描述:
输入只包含大写字母的字符串s。(1 ≤ length ≤ 8000)
输出描述:
输出一个整数,为字符串s中字串“CHN”的数量。
示例1
 
输入
CCHNCHN
 
输出
7
 
 

示例2
 
输入
CCHNCHNCHNCHN
 
输出
30
 
AC代码:
技术图片
#include<stdio.h>
#include<string.h>
int main()
{
    char a[100100];
    long long int n,i;
    long long int d=0,b=0,c=0,m;
    scanf("%s",&a);
    m=strlen(a);
    for(i=0;i<m;i++)
    {
        if(a[i]==C)
            d++;
        else if(a[i]==H)
            b+=d;
        else if(a[i]==N)
            c+=b; 
    }
    printf("%lld",c);
    
    return 0;
}
View Code

 

 


以上是关于简单dp的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

为啥这段代码会泄露? (简单的代码片段)

HDU3247 Resource Archiver(AC自动机+BFS+DP)

[bzoj1966][Ahoi2005][VIRUS 病毒检测] (字符串dp)

代码片段 - Golang 实现简单的 Web 服务器