第七天训练小结
感觉单单只有训练小结还是过于平庸了,不能有太大的提高,但是去写专门的知识点类的博客又感觉知识不够,还是需要更加努力才行,不能嘴上说说而已啊
(定个小目标:在放假前把这些都搞懂,年前多刷刷这些题目的基础和提升,找到自己的解题方法和分析题面以及阅读英文题目的习惯)
今天讲的是动态规划
拿到任意一个题目,刚开始对其分析的时候,如果需要对其两个参量(比如字符串的位置以及它最大相同字串、01背包中物品放或者是不放入、还有烤蛋糕小问题)
当我确定一个题目是需要用dp去解决的时候,我要去分析变量之间的关系,分析其中的递推或者是递归的关系,这样才可以找到解决问题的最好的方法
今天的c题滑雪
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。Input输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。Output输出最长区域的长度。Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
Sample Output
25
题意理解:给定一个矩阵,需要找到一个最大的上升路径,其实这题本质上和最简单的那道dp入门题目,走逆三角非常的相似,他们都是去找一个最大的路去走,而本题目中由于需要从大的数字走向小的数字并且是从上下左右4个方向去走,
那么对于任意的一个数字,它的值应该是四周小于它的值+1取其中一个最大的(假设四个全部大于它就取0),而对于四周的值,我们就又要对四周的值再去取四周的值,搜索一个其中的最大值。此时,我们可以采用dfs的做法并且采用优化递归
假设这个值已经有了就直接返回,如果没有再去寻找
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
int max(int x,int y)
{
if(x>y) return x;
return y;
}
int mp[110][110];
int dp[110][110];
int maxp=0;
int maxi,maxj;
int tx[]={0,0,0,1,-1};
int ty[]={0,1,-1,0,0};
int r,c;
int dfs(int x,int y)
{
if(dp[x][y]!=0)
{
return dp[x][y];
}
for(int i=1;i<=4;i++)
{
if(mp[x][y]>mp[x+tx[i]][y+ty[i]]&&x+tx[i]>=1&&x+tx[i]<=r&&y+ty[i]>=1&&y+ty[i]<=c)
{
mp[x][y]=max(mp[x][y],dfs(x+tx[i],y+ty[i])+1);
}
}
}
int main()
{
scanf("%d %d",&r,&c);
memset(dp,0,sizeof dp);
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf("%d",&mp[i][j]);
}
}
int maxp=0;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
maxp=max(maxp,dfs(i,j));
}
}
printf("%d\n",maxp);
return 0;
}
代码如上
01背包的话理解的还是有点不够透彻,需要多看看blog
https://www.cnblogs.com/zyacmer/p/9961710.html
//我认为一个非常好的大佬的博客
Chef Monocarp has just put nn dishes into an oven. He knows that the ii-th dish has its optimal cooking time equal to titi minutes.
At any positive integer minute TT Monocarp can put no more than one dish out of the oven. If the ii-th dish is put out at some minute TT, then its unpleasant value is |T−ti||T−ti| — the absolute difference between TT and titi. Once the dish is out of the oven, it can't go back in.
Monocarp should put all the dishes out of the oven. What is the minimum total unpleasant value Monocarp can obtain?
Input
The first line contains a single integer qq (1≤q≤2001≤q≤200) — the number of testcases.
Then qq testcases follow.
The first line of the testcase contains a single integer nn (1≤n≤2001≤n≤200) — the number of dishes in the oven.
The second line of the testcase contains nn integers t1,t2,…,tnt1,t2,…,tn (1≤ti≤n1≤ti≤n) — the optimal cooking time for each dish.
The sum of nn over all qq testcases doesn't exceed 200200.
Output
Print a single integer for each testcase — the minimum total unpleasant value Monocarp can obtain when he puts out all the dishes out of the oven. Remember that Monocarp can only put the dishes out at positive integer minutes and no more than one dish at any minute.
Example
6 6 4 2 4 4 5 2 7 7 7 7 7 7 7 7 1 1 5 5 1 2 4 3 4 1 4 4 4 21 21 8 1 4 1 5 21 1 8 21 11 21 11 3 12 8 19 15 9 11 13
4 12 0 0 2 21
Note
In the first example Monocarp can put out the dishes at minutes 3,1,5,4,6,23,1,5,4,6,2. That way the total unpleasant value will be |4−3|+|2−1|+|4−5|+|4−4|+|6−5|+|2−2|=4|4−3|+|2−1|+|4−5|+|4−4|+|6−5|+|2−2|=4.
In the second example Monocarp can put out the dishes at minutes 4,5,6,7,8,9,104,5,6,7,8,9,10.
In the third example Monocarp can put out the dish at minute 11.
In the fourth example Monocarp can put out the dishes at minutes 5,1,2,4,35,1,2,4,3.
In the fifth example Monocarp can put out the dishes at minutes 1,3,4,51,3,4,5.
E题题面如上,题面意思是刚开始的时候把所有东西全都放进去,然后需要在不重复的时间把他给取出来
实现方法:开一个数组,i指的是每个菜,j指的是放进去的时间,其实对于每个菜的每个时间都会有放和不放两种选择
所以递推关系式会满足min{dp[i][j-1],dp[i-1][j]+abs(i-a[i])};//前者代表的是不出菜,后者是出菜但是需要减去那个心情的值
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=1e5+10;
#define inf 0x3f3f3f3f;
#define pii pair<int,int>
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int a[101][101];
int dif[101][101]={0};
int r,c;
void bfs(int a,int b)
{
int ans=0;
int x,y,xx,yy;
queue<pii>q;
q.push(make_pair(a,b));
while(!q.empty())
{
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx<r&&yy>=0&&yy<c&&a[xx][yy]>a[x][y])
{ ans++;
q.push(make_pair(xx,yy));
}
}
}
dif[x][y]=max(dif[x][y],ans);
}
int main()
{
cin>>r>>c;
for(int i=0;i<r;i++)//输入矩阵
{
for(int j=0;j<c;j++)
cin>>a[i][j];
}
int max1=-inf;
for(int i=0,i<r;i++)
{
for(int j=0;j<c;j++)
{
bfs(i,j);
}
}
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
if(dif[i][j]>max1) max1=dif[i][j];
}
cout<<max1<<endl;
return 0;
}
代码如上
机会只留给有准备的人,他们懒也是因为他们有能力有资本懒,自己不能再懒下去了

浙公网安备 33010602011771号