动态规划类题型

编程入门 行业动态 更新时间:2024-10-07 17:32:58

动态规划类<a href=https://www.elefans.com/category/jswz/34/1767307.html style=题型"/>

动态规划类题型

法兰要塞(zzulioj周赛7)

题目描述

“分享狼血,与子同胞”
“漫步深渊,心怀正义”
“侍奉光明,斩杀黑暗”
“因剑而生,因剑而死”
“深渊无尽,我等将不娶妻,不生子,只求一世荣耀”
“光阴有时,我等必守此誓,献此生,但愿诸界太平”
无火的余烬,你追随者古老的誓言来到了法兰要塞,为了通过烽火试炼,你必须收集足够多的灵魂。
已知要塞里有n个怪物,不同的怪物有着不同的血量a。每次,你可以选择消灭一只怪物,同时所有血量为a+1和a-1的怪物也会死去。同时你可以获得a个灵魂。

输入

第一行输入一个整数n(1<=n<=10^5)
第二行输入n个整数a1,a2,…an(1<=ai<=10^5)

输出

请输出无火的余烬可以获得的最大灵魂数量

样例输入

9
1 2 1 3 2 2 2 2 3

样例输出

10

分析

对于n个血量的怪物,可以从小到大对其进行动态规划思想。从1开始(因为从单侧开始只需要考虑i+1即可),dp[1][0]为不杀该怪物的灵魂,dp[1][1]为杀该怪物的灵魂。随后分析i+1的dp,即2的dp。由于怪物最大血量为10^5 ,则dp[10^5]即为最终求值

标程

#include<bits/stdc++.h>
using namespace std;
long long soul[100005],s[100005],dp[100005][2];
int main()
{int n,a;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a);soul[a]+=a;  //soul是指a血的怪物全部杀掉可以获得的灵魂}for(int i=1;i<=100005;i++)   //此处i指怪物血量 {dp[i][0]=max(dp[i-1][1],dp[i-1][0]);dp[i][1]=dp[i-1][0]+soul[i];}long long ans=max(dp[100005][1],dp[100005][0]);printf("%lld",ans);
}

学长的棒棒糖(zzulioj周赛7)

题目描述

学长有n个棒棒糖,他每次最多可以吃k个,请问他有多少种方法来吃棒棒糖

输入

输入两个整数n, k(1 <= n <= 100000) (1 <= k <= 100)

输出

一个正整数,为不同方法数,由于答案可能很大,你需要输出对答案mod100003的结果。

样例输入

5 2

样例输出

8

提示

8种例子如下:
1-1-1-1-1
2-1-1-1
1-2-1-1
1-1-2-1
1-1-1-2
2-2-1
2-1-2
1-2-2

分析

不太明白为什么要用到dp,目前仅仅只能通过找规律发现规律满足n前k项dp相加之和,如n=5,k=3
dp[5]=dp[4]+dp[3]+dp[2]

标程

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,k,dp[100005];memset(dp,0,sizeof(dp));scanf("%d%d",&n,&k);dp[0]=1;dp[1]=1;for(int i=2;i<=n;i++){for(int j=1;j<=k;j++){if(i-j<0)break;dp[i]+=dp[i-j];dp[i]=dp[i]%100003;}}printf("%d",dp[n]);} 

hdu 1087 Super Jumping! Jumping! Jumping!

现在,有一种象棋游戏叫“超级跳跃!跳跃的!跳跃的!“在HDU非常流行也许你是个好孩子,对这项运动知之甚少,所以我现在就给你介绍一下。
这个游戏可以由两个或两个以上的玩家玩。它由一个棋盘(棋盘)和一些棋子(棋子)组成,所有棋子都用正整数或“开始”或“结束”标记。玩家从起点开始,最后必须跳入终点。在跳跃的过程中,玩家将访问路径中的棋子,但是每个人都必须从一个棋子跳到另一个棋子绝对大(你可以假定起点是最小的,终点是最大的)。所有玩家都不能倒退。一跳可以从一个棋子跳到另一个棋子,也可以跨越许多棋子,甚至你可以直接从起点跳到终点。在这种情况下你当然得零分一个运动员是胜利者,只要他能根据他的跳跃解决方案得到更大的分数。注意,你的分数来自于你跳跃路径中棋子的价值之和。
你的任务是根据给定的棋子列表输出最大值。

Input

输入包含多个测试用例。每个测试用例在一行中描述如下:
N value_1 value_2 …value_N
保证N不大于1000,且所有值均在int范围内。
以0开头的测试用例终止输入,不处理此测试用例。

Output

对于每种情况,按规则打印最大值,一行打印一次。

Sample Input

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

Sample Output

4
10
3

分析

和法兰要塞思路不同,并没有分开讨论1和0两种情况,思维方式有待提高

#include<iostream>
#include<algorithm>
using namespace std;
int a[1005],dp[1005];
int main()
{int n;while(scanf("%d",&n)!=EOF && n){for(int i=1;i<=n;i++){scanf("%d",&a[i]);dp[i]=a[i];}for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if(a[i]>a[j])dp[i]=max(dp[i],dp[j]+a[i]);}}int ans=0;for(int i=1;i<=n;i++)ans=max(ans,dp[i]);printf("%d\n",ans);}
}

LCS

郭哥与瑞瑞在玩一个游戏。

他们先各自写下一串字符,然后互相展示。展示过后,他们再从自己写的那串字符中依次挑出若干字符(保持原有顺序不变),组成新的一串。他们希望自己新组成的字符串与对方新组成的完全相同,并且尽可能长。

例如,郭哥写下abcde,瑞瑞写下aeiou,然后郭哥挑出自己那串里的第1和第5个字符组成新串ae,瑞瑞挑出自己那串中的第1、2个字符,也组成字符串ae。ae就是他们能共同挑出的最长串。

现在,郭哥和瑞瑞分别写出了自己的字符串,请帮他们算一下他们能共同挑出组成的字符串最长有多长。

Input

输入包含多组数据,处理至文件结尾。

每组数据占一行,包括以空格分隔的两个字符串,分别是郭哥和瑞瑞写下的字符串。两个字符串长度都在1000以内。

Output

对于每组输入,输出一个整数,即他们能共同挑出组成的字符串的最大长度。

Sample Input

abcfbc abfcab
programming contest
abcd mnp

Sample Output

4
2
0

dp[i][j]表示第一个字符串i个字符和第二个j个字符匹配的话可以 截至i和j的位置可以拥有的最大数量

更多推荐

动态规划类题型

本文发布于:2024-02-28 01:47:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1767573.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:题型   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!