• 背包简记


    背包问题的思想很不错,个人学习后收获很多。它是将一个问题分解成若干个子问题,并以解决子问题达到解决原问题的一种解题思想。接下来我准备复习一下3个简单的背包问题,以便日后回忆起来能很快。

    1:数塔问题

    题目:HDU 2084.

    解题思想:每下一层的最大值都能通过上一层的遍历得到,只要不断记录下一层就能得到的最低层的最大结果。(应该是背包问题中最简单的了吧);

    代码如下:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int max(int a,int b)
     5 {
     6 return a>b?a:b;
     7 }
     8 
     9 int main()
    10 {
    11 int n;//多组输入; 
    12 while(cin>>n)
    13 {
    14 while(n--)
    15 {
    16 int m,a[105][105]={0},dp[105][105],ans=-1;
    17 cin>>m;//数塔层数; 
    18 for(int i=1;i<=m;i++)
    19 for(int j=1;j<=i;j++)
    20 cin>>a[i][j];
    21 memset(dp,0,sizeof(dp));
    22 for(int i=1;i<=m;i++)
    23 for(int j=1;j<=i;j++)
    24 dp[i][j]=a[i][j]+max(dp[i-1][j-1],dp[i-1][j]);//记录每一层的最大值; 
    25 for(int j=1;j<=m;j++)
    26 ans=max(ans,dp[m][j]);//比较最低一层的最大数据; 
    27 cout<<ans<<endl;
    28 }
    29 }
    30 return 0;
    31 }

    2:最长增序列

    题目:百练 2757.

    解题思想:记录每个数之前的最大增序列,最后遍历一遍记录数据,得到最大增序列长度;(难度略稍于数塔之后,属于简单的背包问题);

    代码如下:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int max(int a,int b)
     5 {
     6 return a>b?a:b;
     7 }
     8 
     9 int main()
    10 {
    11 int n;//数组长度; 
    12 while(cin>>n)
    13 {
    14 int dp[35],a[35],ans=0; 
    15 for(int i=1;i<=n;i++)
    16 cin>>a[i];
    17 memset(dp,0,sizeof(dp));
    18 for(int i=1;i<=n;i++)//遍历到第i个数; 
    19 for(int j=1;j<=i;j++)//遍历第一个数到到这第i个数; 
    20 if(a[i]>a[j]) 
    21 dp[i]=max(dp[j]+1,dp[i]);// 不断更新第i个数之前的最长增序列有多少个 ;
    22 for(int i=1;i<=n;i++) 
    23 ans=max(dp[i],ans);//最后遍历一遍记录数据; 
    24 cout<<ans+1<<endl;
    25 }
    26 return 0;
    27 }

    /*

    举个例子好理解:

    8

    3 7 1 8 2 5 6 9

    第一个数是3;3之前没有比3小的数,所以dp[1]=0;第二个数是7;之前有比它小的3,所以dp[2]=1;接着dp[3]=0;到dp[4]时,遍历dp[1]时,因为满足8>3,暂时dp[4]更新为1;遍历到dp[2]时,因为8>7,此时dp[2](为2)>当时dp[4](为1)所以,dp[4]更新为2;再遍历dp[3]时,虽然8>1,但此时dp[4]>dp[3],所以dp[4]保留原值2......一直到9时,dp[8]更新为4;最后遍历一遍dp[1]-dp[8]:0,1,0,2,1,2,3,4得到dp[8]最大,所以最长增序列为dp[8]+1=5(加9本身);

    */

    3.01背包问题

    题目:HDU 2546(一类题)

    解题思想:01背包就是拿与不拿的问题;当给定一个背包容器,各物体重量和价值时,我们就一个一个来试试,并把我们试的数据储存下来(试的时候用到了辅助背包,就是重量为1到背包最大重量的背包,怎么用等下讲),方便下一次试的时候在已有的数据里拿出最大的那组数据;(就是解决子问题嘛,为方便回忆,等下列出01背包表并详细解释表格的数据代表什么,便于灵活运用)

    代码如下:

     1 #include<iostream> 
     2 #include<cstring>
     3 using namespace std;
     4 int max(int a,int b)
     5 {
     6     return a>b?a:b;
     7 }
     8 
     9 int main()
    10 {
    11     int num,maxspace;//num代表背包个数,maxspace代表背包最大容量 
    12     while(cin>>num>>maxspace)
    13     {
    14         int weight[10],value[10],dp[11][100];//weight为每个背包重量,value为每个背包价值 
    15         for(int i=1;i<=num;i++)
    16         cin>>weight[i];
    17         for(int i=1;i<=num;i++)
    18         cin>>value[i];
    19         memset(dp,0,sizeof(dp));
    20         for(int i=1;i<=num;i++)//尝试第i个背包 
    21         for(int j=1;j<=maxspace;j++)//重量为1到maxspace重的背包来尝试第i个背包 
    22         if(j>=weight[i])//如果承重为j的背包可以放 
    23         dp[i][j]=max(value[i]+dp[i-1][j-weight[i]],dp[i-1][j]);//放入i的价值加上之前以记录承重为j-weight[i] 的最大价值和没加的i-1物体承重为j的最大价值;(绕口) 
    24         else
    25         dp[i][j]=dp[i-1][j];//如果放不下则直接保存i-1物体承重为j的最大价值;(好像不用else也行,因为放不进去的数据不会用到) 
    26         cout<<dp[num][maxspace]<<endl;//dp[num][maxspace]肯定为最大值,等下看表一目了然; 
    27         //以下为打表
    28         for(int i=1;i<=num;i++)
    29         {
    30             for(int j=1;j<=maxspace;j++)
    31                 cout<<dp[i][j]<<"	";
    32             cout<<endl; 
    33         }
    34     }
    35     return 0;
    36 }

    /*

    依然举例说明:

    先说dp[i][j]代表面对前i件物品,辅助背包容量为j时,所取得的最大价值。

    5个物品,背包承重为10;5行从上往下为面对第i个物体,10列为重量1-10的辅助背包;

    先看第一行第一列dp[1][1];因为中量为1的辅助背包不能放下质量为2的第一个物品,所以最大价值为0,之后辅助背包大于等于二后能放,于是dp[1][1]-dp[1][10]都为4;再面对第2个物品,主要看dp[2][3]和dp[2][4];dp[2][3]表示只放了2,而dp[2][4]则为放了4;又在dp[2][6]时的10是因为辅助背包为6时,6>4;可以放入,但值得注意的是,试空间为6的背包时就用到了dp[2-1][6-4]即dp[1][2]时的数据,此时表示刚好放入我就放,我们知道,在此之前的数据都是最大的,此时得出的数据就也是最大的,之后依此类推;再看dp[3][3]辅助背包承重为3时,可以放物体1或3;但物体3的价值大于物体一的价值,于是最大数据就被更新了,总之在得出最大数据时,我们在不断更新最大数据,得出的答案便在最后一个(最后一个数据时从之前的数据得来的)。

    差不多就这样吧,表达能力有限,自己懂就行,其他人,随缘吧。

    */

  • 相关阅读:
    (转)JVM参数的说明、简单记法和GC调优策略
    深度学习论文翻译解析(十二):Fast R-CNN
    深度学习论文翻译解析(十一):OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks
    vue中组建的创建和使用
    CountDownLatch的理解和使用
    java多线程并发编程中对一些概念和关键字的理解
    spring中访问变量的用法
    mysql中group by优化
    vue中实现标题的国际化
    mysql中的覆盖索引,二级索引和索引排序
  • 原文地址:https://www.cnblogs.com/wwq-19990526/p/8606708.html
Copyright © 2020-2023  润新知