zoukankan      html  css  js  c++  java
  • 01背包记录路径 (例题 L3-001 凑零钱 (30分))

    题意:

    就是找出来一个字典序最小的硬币集合,且这个硬币集合里面所有硬币的值的和等于题目中的M

    题解:

    01背包加一下记录路径,如果1硬币不止一个,那我们也不采用多重背包的方式,把每一个1硬币当成一个独立的单位来进行01背包dp

    但是我们知道背包dp的路径可能不止一条,而我们要从中得到字典序最小的序列,我的代码中两次不同的排序会得到最大/小字典序

    降序 == 最小字典序

    升序 == 最大字典序

     1 #include<iostream>
     2 #include<queue>
     3 #include<vector>
     4 #include<string.h>
     5 #include<stdio.h>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=5e4+10;
    10 const int N=1e4+10;
    11 int v[N];
    12 int vv[N];
    13 int dp[N];
    14 bool pre[N][105];
    15 int main()
    16 {
    17     int m,n;
    18     scanf("%d%d",&n,&m);
    19     for(int i=1; i<=n; i++)
    20     {
    21         scanf("%d",&v[i]);
    22     }
    23     sort(v+1,v+n+1);  //从大到小排序那么答案输出就是最小字典序,如果是从小到大排序,那么答案输出
    24     //就是最大字典序(这就是结论),greater<int>()
    25     memset(dp,0,sizeof(dp));
    26     memset(pre,0,sizeof(pre));
    27     for(int i=1; i<=n; i++)
    28     {
    29         for(int j=m; j>=v[i]; j--)
    30         {
    31             if(dp[j]<=dp[j-v[i]]+v[i])
    32             {
    33                 dp[j]=dp[j-v[i]]+v[i];
    34                 pre[i][j]=1;//如果第i个歌曲被放进背包,,标记当前背包的位置,记录路径;
    35             }
    36         }
    37     }
    38     if(dp[m]!=m)
    39     {
    40         printf("No Solution
    ");
    41         return 0;
    42     }
    43     int i=n,j=m,flag=0;  //这里的初赋值可不能随意改(控制输出最后最大/小字典序就是sort排序和这里,至于为什么可以画一下图)
    44     while(i>=1&&j>=0)
    45     {
    46         if(pre[i][j])
    47         {
    48             if(!flag)
    49                 printf("%d",v[i]),flag=1;
    50             else printf(" %d",v[i]);
    51             j=j-v[i];//第i张歌曲放在了第当背包容量为j-v[i]时,下一步找第i-1张歌曲.(由此的来dp[j]=dp[j-v[i]]+v[i];)
    52         }
    53         i--;
    54     }
    55     return 0;
    56 }

    我对多重背包记录路径和完全背包记录路径

    1、对于多重背包记录路径

    第一种方法就是像这一道题一样,把多重背包当作01背包来写,但是这样时间复杂度肯定高

    2、完全背包都不限制数量了,那记录路径就没有意义了

  • 相关阅读:
    C++ std::stack 基本用法
    linux6 安装 ntopng
    linux 6安装 redis2.6
    Linux6搭建Tomcat服务器
    EXSI6.5忘记root密码
    python3笔记--数字
    python3笔记--运算符
    python3基本数据类型
    python3笔记
    centos6.X升级python3.X方法
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12581280.html
Copyright © 2011-2022 走看看