3月7-第十次机试课记录

动态规划

反思和总结

  • 如果区分是否需要使用dp

    • 一般是最优解问题
    • 一般贪心不能正确处理
  • dp几个要素

    • 状态的定义
      • 几个维度
      • 怎么体现不同的状态
    • 状态的转移
      • 什么东西变动会造成状态转移
    • 状态的启动
      • 一方面定义初值
      • 另一方面确定循环开始的地方,有的时候是从顶向下开始循环,故需要使用记忆化搜索 + 递归的方式
  • 背包

    • 01背包

      //01背包基本的写法
      for(int i = 1; i <= n; i ++){
      	for(int j = c; j >= 0; j --){
      		if(j > weight[i])
      			dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + v[i]);
      		else
      			dp[i][j] = dp[i - 1][j];
      	}
      }
      
      //01背包优化写法
      for(int i = 1; i <= n; i ++){
          for(int j = c; j >= w[i]; j --){
      		dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
      	}
      }
      
      //完全背包(一个物品可以取多次)
      for(int i = 1; i <= n; i ++){
          for(int j = w[i]; j <= c; j ++){
      		dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
      	}
      }
      

题号

  • PIPIOJ 1071: 数塔

  • PIPIOJ 1073: 矩阵取数Ⅰ

  • PIPIOJ 1076: 饭卡

  • PIPIOJ 1078: 等待分配的程序

  • PIPIOJ 1079: PIPI的存钱罐

  • PIPIOJ 1080: 最长上升子序列Ⅰ

  • PIPIOJ 1083: 最长公共子序列Ⅰ

  • PIPIOJ 1092: 地头蛇PIPI

  • PIPIOJ 1022: 淘金

  • PIPIOJ 1093: 滑雪

  • PIPIOJ 1088: 回文串询问Ⅱ

  • PIPIOJ 1019: 堆石子

分析

  • 1076
    • 问题可以拆分为少5快钱容量的背包问题 + 用5块钱买最多东西的贪心问题
  • 1078
    • 问题可以化解为在总时间/2的情况下,选择尽可能多的东西,也是背包问题
    • 考虑两个背包一起拿东西不方便,直接从结果的情况出发分析,猜出最终的大致情况,从而降维成为单背包问题
  • 1079
    • 也是背包问题,只是这题需要对dp初值设置为INF,而dp00设置为0,并且是最小背包问题,从而使得刚好选择合适容量的有解
  • 1080
    • 这题要是最长上升子序列,要和最大连续和区分
    • 状态的定义为对应下标的最大长度
    • 状态的更新,由于是子序列,不是子串,所以需要从当前下标向前看,找到满足条件的最大值
  • 1083
    • 状态的定义是对应下标的字符串包含的子序列长度
    • 状态的转移取绝于当前字符
  • 1092
    • 状态的定义包含了两种的可能,状态的转移就是在不同的可能中移动
  • 1022
    • 降维,先按1092算出所有的行,在将行看成一列,再次来一次1092
  • 1093
    • 记忆化搜索,从上往下寻找,使用dp定义状态,保存数据
  • 1088
    • 一方面使用dp来判断是不是回文串
    • 另一方面来使用容斥定理计算回文串子串的个数
    • 两者可以同时进行
  • 1019
    • 这题也是从下往上搜索,故需要记忆化搜索
posted @ 2020-03-07 16:10  fabe2ry  阅读(236)  评论(0编辑  收藏  举报