杭电ACM-LCY算法进阶培训班-专题训练(区间dp)

2023-11-20 21:20

本文主要是介绍杭电ACM-LCY算法进阶培训班-专题训练(区间dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

杭电ACM-LCY算法进阶培训班-专题训练(区间dp)

  • 杭电ACM-LCY算法进阶培训班-专题训练(区间dp)
    • Two Rabbits
    • Dire Wolf
    • String painter
    • You Are the One

Two Rabbits

Problem Description
Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they planned to play a game with some stones. There were n stones on the ground and they were arranged as a clockwise ring. That is to say, the first stone was adjacent to the second stone and the n-th stone, and the second stone is adjacent to the first stone and the third stone, and so on. The weight of the i-th stone is ai.

The rabbits jumped from one stone to another. Tom always jumped clockwise, and Jerry always jumped anticlockwise.

At the beginning, the rabbits both choose a stone and stand on it. Then at each turn, Tom should choose a stone which have not been stepped by itself and then jumped to it, and Jerry should do the same thing as Tom, but the jumping direction is anti-clockwise.

For some unknown reason, at any time , the weight of the two stones on which the two rabbits stood should be equal. Besides, any rabbit couldn’t jump over a stone which have been stepped by itself. In other words, if the Tom had stood on the second stone, it cannot jump from the first stone to the third stone or from the n-the stone to the 4-th stone.

Please note that during the whole process, it was OK for the two rabbits to stand on a same stone at the same time.

Now they want to find out the maximum turns they can play if they follow the optimal strategy.

Input
The input contains at most 20 test cases.
For each test cases, the first line contains a integer n denoting the number of stones.
The next line contains n integers separated by space, and the i-th integer ai denotes the weight of the i-th stone.(1 <= n <= 1000, 1 <= ai <= 1000)
The input ends with n = 0.

Output
For each test case, print a integer denoting the maximum turns.

Sample Input

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

Sample Output

1
4
5

Hint

For the second case, the path of the Tom is 1, 2, 3, 4, and the path of Jerry is 1, 4, 3, 2.
For the third case, the path of Tom is 1,2,3,4,5 and the path of Jerry is 4,3,2,1,5.

思路
两只兔子各选一块石头(重量相等),一只顺时针走,另一只逆时针走。最大的步数等于将原石头序列分为左右两部分,求两部分的最大回文子序列长度之和。
在这里插入图片描述
画个很粗糙的图解释一下为什么要将原序列分成左右两端,且答案为这两段的最大回文子序列长度之和:
例如,两只兔子最初都站在s[3]=1这块石头上(图中方块标出),第一只兔子(上方箭头)往右走,第二只(下方箭头)往左走。假设第一只兔子已经踩过的石头为1、2(上方横线标出),第二只也踩过1、2(下方横线标出)。在上面这两步中,兔子们踩的石头正好是序列2、1、1、2中的回文(尽管现在不是最大的回文子串)。
下一步,假设两只兔子都踩了3,这又是1、3这个序列的回文。
再下一步、两只兔子都踩2,这也是最后一步了,又回到了2、1、1、2这个序列中。
所以,在上面这个例子中,把2、1、1、2、1、3分为了2、1、1、2和1、3这左右两部分,兔子踩过的数都属于这两部分的回文子序列:”2、1、2“、”3“。
不过,由于起始位置的原因,兔子踩了这两个序列中的回文子序列,并没有踩最大回文子序列。不过,显然存在一种走法,使得兔子能够踩到最大回文子序列。
上面的例子只举例了两只兔子同起点的情况,当它们起点不在同一块石头上时,依然可以看作踩了左右两部分的回文子序列。
所以,问题就转化为,求一个序列中的所有子序列的最大回文子序列长度(有点绕,就是解决所有的子问题)。这里可以用动态规划来求出所有子问题的答案。
状态转移方程为:
d p [ i ] [ j ] = { d p [ i + 1 ] [ j − 1 ] + 2 , s [ i ] = = s [ j ] m a x ( d p [ i + 1 ] [ j ] , d p [ i ] [ j − 1 ] ) , d p [ i − 1 ] [ j − 1 ] = 1 dp[i][j]=\left\{ \begin{aligned} dp[i+1][j-1]+2 &,s[i]==s[j] \\ max(dp[i+1][j],dp[i][j-1]) &,dp[i-1][j-1]=1\\ \end{aligned} \right. dp[i][j]={dp[i+1][j1]+2max(dp[i+1][j],dp[i][j1])s[i]==s[j]dp[i1][j1]=1
d p [ i ] [ j ] dp[i][j] dp[i][j]代表 [ i , j ] [i,j] [i,j]这个区间的最大回文子序列长度。

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

Dire Wolf

Problem Description
Dire wolves, also known as Dark wolves, are extraordinarily large and powerful wolves. Many, if not all, Dire Wolves appear to originate from Draenor.
Dire wolves look like normal wolves, but these creatures are of nearly twice the size. These powerful beasts, 8 - 9 feet long and weighing 600 - 800 pounds, are the most well-known orc mounts. As tall as a man, these great wolves have long tusked jaws that look like they could snap an iron bar. They have burning red eyes. Dire wolves are mottled gray or black in color. Dire wolves thrive in the northern regions of Kalimdor and in Mulgore.
Dire wolves are efficient pack hunters that kill anything they catch. They prefer to attack in packs, surrounding and flanking a foe when they can.
— Wowpedia, Your wiki guide to the World of Warcra

Matt, an adventurer from the Eastern Kingdoms, meets a pack of dire wolves. There are N wolves standing in a row (numbered with 1 to N from left to right). Matt has to defeat all of them to survive.

Once Matt defeats a dire wolf, he will take some damage which is equal to the wolf’s current attack. As gregarious beasts, each dire wolf i can increase its adjacent wolves’ attack by bi. Thus, each dire wolf i’s current attack consists of two parts, its basic attack ai and the extra attack provided by the current adjacent wolves. The increase of attack is temporary. Once a wolf is defeated, its adjacent wolves will no longer get extra attack from it. However, these two wolves (if exist) will become adjacent to each other now.

For example, suppose there are 3 dire wolves standing in a row, whose basic attacks ai are (3, 5, 7), respectively. The extra attacks bi they can provide are (8, 2, 0). Thus, the current attacks of them are (5, 13, 9). If Matt defeats the second wolf first, he will get 13 points of damage and the alive wolves’ current attacks become (3, 15).

As an alert and resourceful adventurer, Matt can decide the order of the dire wolves he defeats. Therefore, he wants to know the least damage he has to take to defeat all the wolves.

Input
The first line contains only one integer T , which indicates the number of test cases. For each test case, the first line contains only one integer N (2 ≤ N ≤ 200).

The second line contains N integers ai (0 ≤ ai ≤ 100000), denoting the basic attack of each dire wolf.

The third line contains N integers bi (0 ≤ bi ≤ 50000), denoting the extra attack each dire wolf can provide.

Output
For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1), y is the least damage Matt needs to take.

Sample Input

2
3
3 5 7
8 2 0
10
1 3 5 7 9 2 4 6 8 10
9 4 1 2 1 2 1 4 5 1

Sample Output
Case #1: 17
Case #2: 74

Hint
In the first sample, Matt defeats the dire wolves from left to right. He takes 5 + 5 + 7 = 17 points of damage which is the least damage he has to take.

题意
n n n只狼排成一排,每只狼有一个直接伤害和一个辅助伤害,当你打败第 i i i只狼时,会受到第 i i i只狼的直接伤害和它左右两只狼的辅助伤害。打败第 i i i只狼后,它左右两只狼相邻。
思路
d p [ i ] [ j ] dp[i][j] dp[i][j]代表打败 [ i , j ] [i,j] [i,j]这个区间内所有的狼受到的伤害,特别注意:这里并没有把第 i − 1 i-1 i1 j + 1 j+1 j+1只狼的辅助伤害计入
状态转移方程为:
d p [ i ] [ j ] = m i n i < = k < = j { d p [ i ] [ k − 1 ] + d p [ k + 1 ] [ j ] + a [ k ] + b [ i − 1 ] + b [ j + 1 ] } dp[i][j]=min_{i<=k<=j}\{dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]\} dp[i][j]=mini<=k<=j{dp[i][k1]+dp[k+1][j]+a[k]+b[i1]+b[j+1]}
状态转移方程的意义为:最后打败第k只狼,先打败区间 [ i , k − 1 ] [i,k-1] [i,k1] [ k + 1 , j ] [k+1,j] [k+1,j]两个区间的狼

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=205;
int te,n,dp[maxn][maxn],a[maxn],b[maxn],ca;int main(){scanf("%d",&te);while(te--){scanf("%d",&n);memset(dp,0,sizeof(dp));memset(b,0,sizeof(b));for(int i=1;i<=n;i++)   scanf("%d",&a[i]);for(int i=1;i<=n;i++)   scanf("%d",&b[i]);for(int len=1;len<=n;len++){for(int i=1;i+len-1<=n;i++){int j=i+len-1;dp[i][j]=1e9;for(int k=i;k<=j;k++)dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]);}}printf("Case #%d: %d\n",++ca,dp[1][n]);}
}

String painter

Problem Description
There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?

Input
Input contains multiple cases. Each case consists of two lines:
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.

Output
A single line contains one integer representing the answer.

Sample Input

zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd

Sample Output

6
7

思路
先计算一个空串涂为b所需的次数,再计算a涂为b的次数。
f [ i ] [ j ] f[i][j] f[i][j]代表把一个空串涂为b的[i,j]区间需要的最少次数,那么:
f [ i ] [ j ] = { f [ i ] [ j − 1 ] , b [ i ] = = s [ j ] m i n ( f [ i ] [ k ] + f [ k + 1 ] [ j ] ) , e l s e f[i][j]=\left\{ \begin{aligned} f[i][j-1] ,b[i]==s[j] \\ min(f[i][k]+f[k+1][j]) ,else\\ \end{aligned} \right. f[i][j]={f[i][j1]b[i]==s[j]min(f[i][k]+f[k+1][j])else

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110,inf=0x3f3f3f3f;
char a[maxn],b[maxn];
int f[maxn][maxn],dp[maxn],n;int main(){while(~scanf("%s%s",a+1,b+1)){n=strlen(a+1);for(int i=1;i<=n;i++)   f[i][i]=1;for(int len=2;len<=n;len++)for(int i=1;i+len-1<=n;i++){int j=i+len-1;f[i][j]=inf;if(b[i]==b[j])  f[i][j]=f[i][j-1];else    for(int k=i;k<j;k++)f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);}for(int i=1;i<=n;i++)   dp[i]=i==1?a[i]!=b[i]:inf;for(int i=2;i<=n;i++)if(a[i]==b[i])  dp[i]=dp[i-1];else    for(int j=0;j<i;j++)   dp[i]=min(dp[i],dp[j]+f[j+1][i]);printf("%d\n",dp[n]);}
}

You Are the One

Problem Description
  The TV shows such as You Are the One has been very popular. In order to meet the need of boys who are still single, TJUT hold the show itself. The show is hold in the Small hall, so it attract a lot of boys and girls. Now there are n boys enrolling in. At the beginning, the n boys stand in a row and go to the stage one by one. However, the director suddenly knows that very boy has a value of diaosi D, if the boy is k-th one go to the stage, the unhappiness of him will be (k-1)*D, because he has to wait for (k-1) people. Luckily, there is a dark room in the Small hall, so the director can put the boy into the dark room temporarily and let the boys behind his go to stage before him. For the dark room is very narrow, the boy who first get into dark room has to leave last. The director wants to change the order of boys by the dark room, so the summary of unhappiness will be least. Can you help him?

Input
  The first line contains a single integer T, the number of test cases. For each case, the first line is n (0 < n <= 100)
  The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)

Output
  For each test case, output the least summary of unhappiness .

Sample Input

2 
5
1 2 3 4 5
5
5 4 3 2 2

Sample Output

Case #1: 20
Case #2: 24

思路
d p [ i ] [ j ] = m i n ( d p [ i + 1 ] [ k ] + d p [ k + 1 ] [ j ] + ( k − i ) ∗ a [ i ] + ( k − i + 1 ) ∗ s u m k + 1 , j ) dp[i][j]=min(dp[i+1][k]+dp[k+1][j]+(k-i)*a[i]+(k-i+1)*sum_{k+1,j}) dp[i][j]=min(dp[i+1][k]+dp[k+1][j]+(ki)a[i]+(ki+1)sumk+1,j)
d p [ i ] [ j ] dp[i][j] dp[i][j]代表第i个到第j个人第一个出场时的焦虑值。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
int te,n,ca,a[maxn],dp[maxn][maxn],sum[maxn];int main(){scanf("%d",&te);while(te--){memset(dp,0,sizeof(dp));memset(sum,0,sizeof(sum));scanf("%d",&n);for(int i=1;i<=n;i++)   scanf("%d",&a[i]);for(int i=n;i>0;i--)    sum[i]=sum[i+1]+a[i];for(int len=2;len<=n;len++)for(int i=1;i+len-1<=n;i++){int j=i+len-1;dp[i][j]=dp[i+1][j]+sum[i+1]-sum[j+1];for(int k=i+1;k<=j;k++)dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]+(k-i)*a[i]+(k-i+1)*(sum[k+1]-sum[j+1]));}printf("Case #%d: %d\n",++ca,dp[1][n]);}
}

这篇关于杭电ACM-LCY算法进阶培训班-专题训练(区间dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/397518

相关文章

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖