半条命16吧 关注:393贴子:26,042
  • 8回复贴,共1

三道简单动态规划的题

只看楼主收藏回复



IP属地:河南1楼2022-01-16 21:32回复


    IP属地:河南2楼2022-01-16 21:34
    回复
      我们逐步分析
      01背包这道题,表示出了什么样的集合?在给定前i 个物品的时候,总装入体积不大于j 的最大价值的集合。在属性方面,就是求最大值。
      我们可以设一个二维数组f[i][j] 来表示所有可能的结果。其中,f[i][j]代表的意思是前i个物品在总重不大于j的情况下的最优解。
      当打算装入下一个物品之前,我们要判断下一个物品能否装入现在的背包。当下一个物品装不进去时(在矩阵中表现为不开放第二个物品),f[i][j]=f[i-1][j]. 当下一个物品可以装入的时候,f[i][j]=f[i-1][j-vi]+wi,即在前一个满足重量条件的情况下的装入第i个物品时候的价值。对这两个取最大值即可。
      代码如下
      for (int i = 1; i < N+1; i++) {
      for (int j = 1; j < V+1; j++) {
      if(j<v[i]) f[i][j]=f[i-1][j];
      else f[i][j]=Math.max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
      }
      }


      IP属地:河南3楼2022-01-16 21:51
      回复



        IP属地:河南4楼2022-01-16 21:52
        回复
          这道题的输入可能有点费解,不过其实只是形成了一个二维数组
          我们直接看核心部分
          因为想要到达左下角[i][j],只有两种可能,一是从[i][j-1]向右走一步,二是从[i-1][j]向下走一步。由这个可以向上递推到[0][0]。到达[i][j]的目的也是采花生,我们到达[i][j]处采到的花生的数量,就是max(在[i-1][j]采到的花生,在[i][j-1]采到的花生)再加上在[i][j]处采到的花生。这个也即我们得到的最终状态转移方程
          for (int j = 1; j <=R; j++) {
          for (int k = 1; k <=C ; k++) {
          f[j][k]=Math.max(f[j-1][k],f[j][k-1])+peanuts[j][k];
          }
          }


          IP属地:河南6楼2022-01-16 22:13
          回复


            IP属地:河南7楼2022-01-16 22:14
            回复
              我们先设,这一串序列为nums[],并且令f[i]都为1,f[i]的意义是以第i个为结尾的上升子序列长度。当他们都不严格递增的时候,结果就都是1
              这道题的核心在于,我们可以注意到,当nums[i]>nums[j]的时候,如果f[j]+1>f[i],则f[i]=max(f[j]+1,f[i]),在这样的一轮下来之后,我们直接求f[]中的最大值即可(动态规划问题未必都是打印最后的f[n]或者f[n][m],切忌思维定式)
              f[i] = max(f[i], f[j] + 1)
              ----------
              int max=1;
              for (int i = 0; i < T; i++) {
              f[i]=1;
              for (int j = 0; j < i; j++) {
              if(nums[i]>nums[j]) f[i]=Math.max(f[i],f[j]+1);
              }
              max=Math.max(max,f[i]);
              }
              System.out.println(max);


              IP属地:河南9楼2022-01-17 01:37
              回复
                老哥是不是在准备蓝桥


                IP属地:河南来自Android客户端11楼2022-03-09 23:12
                收起回复