2020.2.8铁一寒假收官赛题解
Posted bigyellowdog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.2.8铁一寒假收官赛题解相关的知识,希望对你有一定的参考价值。
2020.2.8铁一寒假收官赛题解
- 题目均为原题或改编,已得到题主许可
- 出题人:Memoryヾノ战心
- BigYellowDog选手写了份题解,得到出题人许可
T1
这道题是一道很经典的简单dp模型(不会dp的可以先去自学简单入个门
有O(n方)或者O(nlogn)的做法,数据范围n最大不超200,显然O(n方)算法足矣
题目要求最少抽出几本书,可以转化为求最长“舒服样子”序列的元素个数w。答案即为:n-w
具体思路就是定义数组dp1[], dp2[]
dp1[i]表示从左到右看,以第i个位置为结尾,所能构成的 最长舒服序列 的 书数量
dp2[i]表示从右到左看,以第i个位置为结尾,所能构成的 最长舒服序列 的 书数量
转移方法如下:(下面是dp1[]的转移代码,dp2[]同理)
for(int i=2;i<=n;i++) //枚举i的位置 for(int j=1;j<i;j++) //枚举j的位置,显然i的上一个人必须在他左边,所以不能超过i if(a[i]>a[j]) //必须要i的高度>j的高度才能接上去 dp1[i]=max(dp1[j]+1,dp1[i]); //如果执行到这里就说明i位置可以接到"以j位置为结尾的序列"上,那么"接"和"不接"俩选择,哪个好就选择哪个
如何算答案?只需从1-n枚举每个位置,每个位置的最优答案是dp1[i]+dp2[i]-1(减1是因为位置i统计了两次)。那么最终答案就是(n-取n个位置的最优答案中的最大值)。
感觉自己不太擅长揣测没学过dp同学的心理,所以这篇如写得不明白,还请指出。
T2
- 算法是搜索+完全背包dp。(不会的先去自学简单入个门
- 显然数字1卡片必须选,那么下一张选什么呢?
通过观察了几组小数据我发现每次要选的数字范围为[上一个选的数+1,上一次能组成的最大面值+1]
我不会严谨地证明这个结论,但并不影响做题
得出每次选的数范围后,就可以搜索了。搜索思路即每次从范围中选一个数,然后与前面选的数合在一起算出一个最大面值。如果此时的最大面值>记录的最大面值,就将记录的最大面值更新为此时的最大面值。
这样做估计有30分(没试过),会超时。问题出在了计算最大面值这一步上,可以用背包来优化。
背包思路是定义dp[],dp[i]表示凑出i这个面值最少需要的卡片数。用完全背包模板算出dp数组,然后从1枚举到一个人为设的很大的数,如果dp[i]>n了,那么此时的最大面值就是i-1
此题完全背包代码如下:
//虽说是模板,但建议要去找资料弄懂为什么 memset(dp,0x3f,sizeof(dp)),dp[0]=0; for(int i=1;i<=fro;i++) for(int j=c[i];j<=c[i]*n;j++) dp[j]=min(dp[j],dp[j-c[i]]+1); for(int i=1;i<=c[fro]*n;i++) if(dp[i]>n) return i-1;
T3
- 算法是逻辑分析+贪心
- 我先简化了题意:
- n条序列,每条序列不严格递增,花1h可以取到其中一个序列的头,对于每个序列必须按顺序取。
- 问用n个小时最多取到的最大总价值?
- 于是当时我就画图+手玩得出结论:答案即分别将n个小时用到每一条序列,取最优值。
- 这很好理解,要将每个小时发挥最大的价值。显然是选择用到头的金币最大的序列。那么又因为序列越往后越大,所以在原来的江山上继续奋斗肯定比重零开始做人更优对吧
- 严谨的证明不会
以上是关于2020.2.8铁一寒假收官赛题解的主要内容,如果未能解决你的问题,请参考以下文章
威固的MOM,你的WOW 「 WOW 手武之道」威固巅峰技术交流赛圆满收官