这周一直在刷搜索和dp的题,偶尔碰见dp加搜索的综合题,还打了一场cf,虽然结果不太好,差一点c就出了。自己有点菜,还需慢慢变强

P1052 过河
在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,\cdots,L0,1,⋯,L(其中 LL 是桥的长度)。坐标为 00 的点表示桥的起点,坐标为 LL 的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是 SS 到 TT 之间的任意正整数(包括 S,TS,T)。当青蛙跳到或跳过坐标为 LL 的点时,就算青蛙已经跳出了独木桥。

题目给出独木桥的长度 LL,青蛙跳跃的距离范围 S,TS,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。
思路:数据范围为10^9 ,如果定义10^9的数组肯定会爆栈,所以我们需要离散化,2520是1到10的公倍数,因此从一个点出发,无论青蛙能跳的距离是多少,它一定可以到达距离2520处。所以在前方2520没有石头时,可以将当前点向后移2520或者将后面的点向前移2520;
然后我就顺利的wr了。因为我不会改,但思路就是这样,
状态转移方程:dp[i]=min(dp[i],dp[i-j]+b[i]);
错误代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 0x3f3f3f
int l,m,n,k;
int a[maxn],sum[maxn],b[maxn];
int dp[maxn];
int main()
{ios::sync_with_stdio(0);cin>>l>>m>>n>>k;for(int i=1;i<=k;i++)cin>>a[i];sort(a+1,a+k+1);//dp[0]=0;for(int i=1;i<=k;i++)b[i]=(a[i]-a[i-1])%2520;for(int i=1;i<=k;i++){a[i]=a[i-1]+b[i];sum[a[i]]=1;}l=a[k];memset(dp,maxn,sizeof(dp));dp[0]=0;for(int i=1;i<=n+l;i++){for(int j=m;j<=n;j++){if(i-j>=0)dp[i]=min(dp[i],dp[i-j]);}dp[i]+=sum[i];}int ans=k;for(int i=l;i<l+n;i++)ans=min(ans,dp[i]);cout<<ans;return 0;
}

正解代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 0x3f3f3f
int l,m,n,k;
int a[1005],sum[10005];
bool b[100005];
int dp[maxn];
int main()
{ios::sync_with_stdio(0);cin>>l>>m>>n>>k;for(int i=1;i<=k;i++)cin>>a[i];sort(a,a+k+2);//dp[0]=0;memset(dp,0x3f,sizeof(dp));int temp=0;for (int i = 1; i <= k + 1; i++) {if (a[i] - a[i - 1] <= m * n)temp += a[i] - a[i - 1];elsetemp += (a[i] - a[i - 1]) % n + n;b[temp] = true;}dp[0]=0;for(int i=1;i<n+temp;i++){for(int j=m;j<=n;j++){if((i-j)>=0)dp[i]=min(dp[i],dp[i-j]+b[i]);}}int ans=maxn;for(int i=temp;i<=temp+n;i++)ans=min(ans,dp[i]);cout<<ans;return 0;
}

P1063
在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链。在项链上有 NN 颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。因为只有这样,通过吸盘(吸盘是 Mars 人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。如果前一颗能量珠的头标记为 mm,尾标记为 rr,后一颗能量珠的头标记为 rr,尾标记为 nn,则聚合后释放的能量为 m \times r \times nm×r×n(Mars 单位),新产生的珠子的头标记为 mm,尾标记为 nn。

需要时,Mars 人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。

例如:设 N=4N=4,44 颗珠子的头标记与尾标记依次为 (2,3)(3,5)(5,10)(10,2)(2,3)(3,5)(5,10)(10,2)。我们用记号 \oplus⊕ 表示两颗珠子的聚合操作,(j \oplus k)(j⊕k) 表示第 j,kj,k 两颗珠子聚合后所释放的能量。则第 44 、 11 两颗珠子聚合后释放的能量为:

(4 \oplus 1)=10 \times 2 \times 3=60(4⊕1)=10×2×3=60。

这一串项链可以得到最优值的一个聚合顺序所释放的总能量为:

((4 \oplus 1) \oplus 2) \oplus 3)=10 \times 2 \times 3+10 \times 3 \times 5+10 \times 5 \times 10=710((4⊕1)⊕2)⊕3)=10×2×3+10×3×5+10×5×10=710。
思路:最简的区间dp问题,但是需要破环为链,
状态转移方程:
三重循环,第三重循环依次来取出最大值
dp[l][r]=max(dp[l][r],dp[l][k]+dp[k][r]+a[l]*a[k]*a[r]);

#include<bits/stdc++.h>
using namespace std;
#define maxn 0x3f3f3f
int m,n;
int a[maxn],sum[maxn];
int dp[1005][1005];
int main()
{ios::sync_with_stdio(0);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];a[i+n]=a[i];}for(int i=2;i<=n+1;i++)for(int l=1;l+i-1<=n*2;l++){int r=i+l-1;for(int k=l+1;k<r;k++)dp[l][r]=max(dp[l][r],dp[l][k]+dp[k][r]+a[l]*a[k]*a[r]);}int ans=-1;for(int i=1;i<=n;i++)ans=max(ans,dp[i][i+n]);cout<<ans<<endl;return 0;
}

P1043
丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共 nn 个),你要按顺序将其分为 mm 个部分,各部分内的数字相加,相加所得的 mm 个结果对 1010 取模后再相乘,最终得到一个数 kk。游戏的要求是使你所得的 kk 最大或者最小。

例如,对于下面这圈数字(n=4n=4,m=2m=2):

要求最小值时,((2-1)\bmod10)\times ((4+3)\bmod10)=1\times 7=7((2−1)mod10)×((4+3)mod10)=1×7=7,要求最大值时,为 ((2+4+3)\bmod10)\times (-1\bmod10)=9\times 9=81((2+4+3)mod10)×(−1mod10)=9×9=81。特别值得注意的是,无论是负数还是正数,对 1010 取模的结果均为非负值。

丁丁请你编写程序帮他赢得这个游戏。
思路:和能量项链差不多,多了一个最小值,里面有个小细节,题中被除后需要把负数都要改成正数
除以10取余,现在的数字一定小于10,然后再加上10,然后再除以10取余就可以了,看题解知道的。
dpmx[i][j][1]=((sum[j]-sum[i-1])%10+10)%10;
dpmn[i][j][1]=((sum[j]-sum[i-1])%10+10)%10;

代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 0x3f3f3f
int m,n;
int a[maxn],sum[maxn];
int dpmx[105][105][20];
int dpmn[105][105][20];
int main()
{ios::sync_with_stdio(0);cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];a[i+n]=a[i];}sum[0]=0;for(int i=1;i<=n*2;i++)sum[i]=sum[i-1]+a[i];memset(dpmx,-1,sizeof(dpmx));memset(dpmn,maxn,sizeof(dpmn));for(int i=1;i<=n*2;i++)for(int j=i;j<=n*2;j++){dpmx[i][j][1]=((sum[j]-sum[i-1])%10+10)%10;dpmn[i][j][1]=((sum[j]-sum[i-1])%10+10)%10;}for(int i=2;i<=m;i++)for(int len=2;len<=n;len++)for(int l=1;l<=n*2-len+1;l++){int r=l+len-1;for(int f=max(l,l-2+i);f<r;f++){dpmx[l][r][i]=max(dpmx[l][r][i],dpmx[l][f][i-1]*dpmx[f+1][r][1]);dpmn[l][r][i]=min(dpmn[l][r][i],dpmn[l][f][i-1]*dpmn[f+1][r][1]);}}int mxx=-1;int mnn=maxn;for(int i=1;i<=n;i++){mnn=min(dpmn[i][i+n-1][m],mnn);mxx=max(dpmx[i][i+n-1][m],mxx);}cout<<mnn<<endl;cout<<mxx;return 0;
}

已知有两个字串 A,BA,B 及一组字串变换的规则(至多 66 个规则):
A 1 →B 1
A 2 →B 2
输入格式
输入格式如下:

AA BB
A_1A 1
​B_1B 1
A_2A 2
B_2B 2
|-> 变换规则
… …/

所有字符串长度的上限为 2020。

输出格式
若在 1010 步(包含 1010 步)以内能将 AA 变换为 BB,则输出最少的变换步数;否则输出 NO ANSWER!

思路:这个题思路我完全对,就在最后转换子串的时候,自己对STL有点不熟练,要不这个题就直接a了。利用广搜,然后一一列举,放入队列里面,先弹出的一定是步数最少的,一般来说,广搜是求最优,深搜是求个数
代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 0x3f3f3f
string str1,str2;
int n;
string A[1000],B[1000];
map<string,int> mp;
int ans;
string change(const string &str,int i,int j){string ans = "";if (i+A[j].length() > str.length())return ans;for (int k=0; k < A[j].length();k++)if (str[i+k] != A[j][k])return ans;ans = str.substr(0,i);ans+=B[j];ans+=str.substr(i+A[j].length());return ans;
}
struct Node{string str;int cnt;
};
//Node node;
void BFS(){queue<Node> q;Node temp1;temp1.str=str1;temp1.cnt=0;q.push(temp1);//mp[str1]=0;while(!q.empty()){Node temp=q.front();//cout<<temp.str<<" ";q.pop();if(mp.count(temp.str)==1){continue;}if(temp.str==str2){ans=temp.cnt;//cout<<ans<<" ";break;}mp[temp.str]=1;for(int i=0;i<temp.str.size();i++)for(int j=0;j<n;j++){string strtmp=change(temp.str,i,j);if(strtmp!=""){Node node;node.str=strtmp;node.cnt=temp.cnt+1;q.push(node);}}}if(ans==0||ans>10)cout<<"NO ANSWER!"<<endl;elsecout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin>>str1>>str2;//string A[100],B[100];string a,b;//n=0;while(cin>>a>>b){A[n]=a;B[n]=b;n++;}BFS();return 0;
}

本来当时有事情,没想打的,也没认真去打,可能是这次思路出的比较快吧
然后就写了几道。有空补题,
Codeforces Round #753 (Div. 3)
A
You are given a keyboard that consists of 26 keys. The keys are arranged sequentially in one row in a certain order. Each key corresponds to a unique lowercase Latin letter.

You have to type the word s on this keyboard. It also consists only of lowercase Latin letters.

To type a word, you need to type all its letters consecutively one by one. To type each letter you must position your hand exactly over the corresponding key and press it.

Moving the hand between the keys takes time which is equal to the absolute value of the difference between positions of these keys (the keys are numbered from left to right). No time is spent on pressing the keys and on placing your hand over the first letter of the word.

For example, consider a keyboard where the letters from ‘a’ to ‘z’ are arranged in consecutive alphabetical order. The letters ‘h’, ‘e’, ‘l’ and ‘o’ then are on the positions 8, 5, 12 and 15, respectively. Therefore, it will take |5−8|+|12−5|+|12−12|+|15−12|=13 units of time to type the word “hello”.

Determine how long it will take to print the word s.
思路:map列举26个字母,然后一一相减即可

include <bits/stdc++.h>
using namespace std;
map<char,int>mp;
int n;
char a[500];
int main()
{char str;cin>>n;while(n--){for(int i=1;i<=26;i++){cin>>str;mp[str]=i;}cin>>a;int ans=0;for(int i=0;i<strlen(a)-1;i++){ans+=abs(mp[a[i]]-mp[a[i+1]]);}cout<<ans<<endl;}return 0;

B
The grasshopper is located on the numeric axis at the point with coordinate x0.

Having nothing else to do he starts jumping between integer points on the axis. Making a jump from a point with coordinate x with a distance d to the left moves the grasshopper to a point with a coordinate x−d, while jumping to the right moves him to a point with a coordinate x+d.

The grasshopper is very fond of positive integers, so for each integer i starting with 1 the following holds: exactly i minutes after the start he makes a jump with a distance of exactly i. So, in the first minutes he jumps by 1, then by 2, and so on.

The direction of a jump is determined as follows: if the point where the grasshopper was before the jump has an even coordinate, the grasshopper jumps to the left, otherwise he jumps to the right.

For example, if after 18 consecutive jumps he arrives at the point with a coordinate 7, he will jump by a distance of 19 to the right, since 7 is an odd number, and will end up at a point 7+19=26. Since 26 is an even number, the next jump the grasshopper will make to the left by a distance of 20, and it will move him to the point 26−20=6.

Find exactly which point the grasshopper will be at after exactly n jumps.
思路:本来是没思路的,然后我就在纸上写这个题的过程,发现,没走4步就会走回起点,然后就a了,注意,要判断n是否小于4,不然整除的时候会出错
代码:

#include <bits/stdc++.h>
using namespace std;
int t;
long long m,n;
int main()
{cin>>t;while(t--){cin>>m>>n;if(n<4){if(m%2==0){if(n==0)cout<<m<<endl;else if(n==1)cout<<m-1<<endl;else if(n==2)cout<<m-1+2<<endl;else if(n==3)cout<<m-1+2+3<<endl;}else{if(n==0)cout<<m<<endl;else if(n==1)cout<<m+1<<endl;else if(n==2)cout<<m+1-2<<endl;else if(n==3)cout<<m+1-2-3<<endl;}}else{int k=n%4;if(m%2==0){if(k==0)cout<<m<<endl;else if(k==1)cout<<m-n<<endl;else if(k==2)cout<<m+n-n+1<<endl;else if(k==3)cout<<m+n+n-1-n+2<<endl;}else{if(k==0)cout<<m<<endl;else if(k==1)cout<<m+n<<endl;else if(k==2)cout<<m-1<<endl;else if(k==3)cout<<m-n-n+1+n-2<<endl;}}}return 0;
}

C
Yelisey has an array a of n integers.

If a has length strictly greater than 1, then Yelisei can apply an operation called minimum extraction to it:

First, Yelisei finds the minimal number m in the array. If there are several identical minima, Yelisey can choose any of them.
Then the selected minimal element is removed from the array. After that, m is subtracted from each remaining element.
Thus, after each operation, the length of the array is reduced by 1.

For example, if a=[1,6,−4,−2,−4], then the minimum element in it is a3=−4, which means that after this operation the array will be equal to a=[1−(−4),6−(−4),−2−(−4),−4−(−4)]=[5,10,2,0].

Since Yelisey likes big numbers, he wants the numbers in the array a to be as big as possible.

Formally speaking, he wants to make the minimum of the numbers in array a to be maximal possible (i.e. he want to maximize a minimum). To do this, Yelisey can apply the minimum extraction operation to the array as many times as he wants (possibly, zero). Note that the operation cannot be applied to an array of length 1.

Help him find what maximal value can the minimal element of the array have after applying several (possibly, zero) minimum extraction operations to the array.
思路:题意很简单,依次取出最小值,然后与其他数相减,直到数组还剩最后一个数,求这些次取出的最小数中最大数,我一想就想到了优先队列,当时就剩10多分钟了,写完代码提交就超时了,暴力解法果然不行,看了题解后才知道,如果我这次也在纸上画一遍过程,我可能也能快速的a掉
暴力错误解法:

#include <bits/stdc++.h>
using namespace std;
int maxn=0x7fffffff;
priority_queue<int,vector<int>,greater<int> >q;
int t;
int n;
int a[10000007];
int ans=-maxn;int main()
{int x;cin>>t;while(t--){ans=-maxn;while(!q.empty())q.pop();cin>>n;for(int i=0;i<n;i++){cin>>x;q.push(x);}if(n==1){cout<<q.top()<<endl;continue;}while(q.size()!=1){ans=max(ans,q.top());//cout<<ans<<" ";int temp=q.top();q.pop();n--;for(int i=0;i<n;i++){int y=q.top();//cout<<y<<" ";a[i]=y-temp;q.pop();}for(int i=0;i<n;i++)q.push(a[i]);ans=max(ans,q.top());}cout<<ans<<endl;}return 0;
}

正解:

#include<iostream>
#include<algorithm>
using namespace std;
int t,n,a[200001],s;
int main(){cin>>t;while(t--){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];sort(a+1,a+1+n);s=a[1];for(int i=1;i<=n;i++)s=max(s,a[i]-a[i-1]);cout<<s<<endl;}
}

加油

2021.11.06总结相关推荐

  1. Interview:算法岗位面试—11.06早上上海某智能驾驶科技公司(创业)笔试+面试之手撕代码、项目考察、比赛考察、图像算法的考察等

    Interview:算法岗位面试-11.06早上上海某智能驾驶科技公司(创业)笔试+面试之手撕代码.项目考察.比赛考察.图像算法的考察等 导读:该公司是在同济某次大型招聘会上投的,当时和HR聊了半个多 ...

  2. 史上最详细微信小程序授权登录与后端SprIngBoot交互操作说明,附源代码,有疑惑大家可以直接留言,蟹蟹 2021.11.29完善更新小程序代码,

    2021.11.29 更新文章 你好,我是博主宁在春,一起学习吧!!! 写这篇文章的原因,主要是因为最近在写毕业设计,用到了小程序,这中间曲曲折折,一言难尽啊.毕业设计真的让人麻脑阔

  3. Daily Report 2012.11.06 刘宇翔

    今天对李忠修改过的match函数进行测试,修正bug,并进行优化. 将中文分词方法加入到算法中,提高了算法的精确度. 但中文分词方法加入到算法后,出现在一些新问题,对新出现的问题进行了修正和优化. 测 ...

  4. 读论文——Pre-Training with Whole Word Masking for Chinese BERT(2021 11.25)

    第一遍 标题以及作者(2021 11.25) 摘要 本文基于BERT,在RoBERTa上进行一系列改进,提出了用于中文的预训练模型MacBERT. 提出了一种新的掩码策略,MLM as correct ...

  5. 首页推荐流支持快捷修改兴趣标签,问答支持展示gif【2021.11.8】

    hello,大家好,这里是「CSDN产品周报」第17期.本次更新主要涉及首页和问答两个产品模块,具体细节请往下看. 一.首页优化 1.「推荐」信息流新增「修改兴趣标签」按钮 从用户需求的角度考虑,对内 ...

  6. 【报告分享】小红书平台2021 11.11期间行业投放分析报告-千瓜数据(附下载)

    摘要:随着平台多元化发展,用户体量增加,小红书逐渐拥抱了更多的年轻用户群体,也给更多的品牌带来了增长机会.据小红书方透露,2021年小红书平台的单日笔记曝光已经超100亿次,且男性用户占比已经达到了3 ...

  7. 2021.11.8-11.14 AI行业周刊(第71期):AI行业经验

    篇章一:行业经验 不同的AI公司,对于AI产品的场景定位不同. 有的公司是面向C端产品.有的公司专门做B端用户. 当然大白所在的公司,也有具体的定位,主要面向智慧金融.智慧机场.智慧城市. 之前,一直 ...

  8. 第13期微生物组-宏基因组分析(线上/线下同时开课,2021.11)

    福利公告:为了响应学员的学习需求,经过易生信培训团队的讨论筹备,现决定安排扩增子16S分析.宏基因组.Python课程和转录组的线上直播课.报名参加线上直播课的老师可在1年内选择参加同课程的一次线下课 ...

  9. 【不忘初心】Win10_LTSC2021_19044.1381_X64_可更新[纯净精简版][2.52G](2021.11.20)

    此版可正常更新补丁,母版来自UUP WIN10_LTSC2021 19044.1288集成补丁到19044.1381为了保证稳定初心的系统全部都是离线精简和优化,非二次封装.系统纯净.流畅.进程少无任 ...

最新文章

  1. linux 环境配置 安装jdk
  2. 一人之力,刷爆三路榜单!信息抽取竞赛夺冠经验分享
  3. 【亚马逊AWS】入门级别实践
  4. 分享 - 普通程序员如何转向AI方向
  5. 情 人 节 快 乐
  6. acwing199.余数之和(除法分块)
  7. [bzoj2127]happiness
  8. label里面的文字换行_如何在JLabel中自动换行文本?
  9. Java屏蔽输入法_技巧:如何禁止输入法切换到全角状态
  10. posix线程使用详解
  11. 企业邮箱地址格式是什么?企业邮箱地址类型汇总
  12. SCCM推送升级Win10
  13. 2022年vue项目使用go.js 2.1去水印
  14. matlab 点云根据法向量投影到六个平面
  15. js git基本命令
  16. 特斯拉充电电流设置多大_特斯拉充电要多久
  17. Mysql向表里插入中文报错解决方法
  18. html5魔塔编辑器安卓版,Mota: 纪元魔塔前传。童年魔塔记忆。使用手机编写的5000行代码...
  19. 【微信小程序】如何引入外部字体样式
  20. 实例十 — FIFO

热门文章

  1. Abaqus中批量对节点施加集中力荷载
  2. 安全(Security)设计原则(1)
  3. 如何保证企业服务器安全-MCK主机加固解决方案
  4. 企业中台最佳实践--什么是中台(一)
  5. CFD基本流程 及 STAR-CCM+ 11.0软件介绍
  6. java调用MySQL数据库
  7. Java 访问MySQL的小例子
  8. 坚持使用Ubuntu
  9. 星号构成的倒立直角三角形图案
  10. Spring事务管理(应对面试)