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个小时用到每一条序列,取最优值。
  • 这很好理解,要将每个小时发挥最大的价值。显然是选择用到头的金币最大的序列。那么又因为序列越往后越大,所以在原来的江山上继续奋斗肯定比重零开始做人更优对吧
  • 严谨的证明不会
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章