• HDU 1114 完全背包 HDU 2191 多重背包


    HDU 1114 Piggy-Bank 完全背包问题、

    想想我们01背包是逆序遍历是为了保证什么?

    保证每件物品只有两种状态,取或者不取.那么正序遍历呢? 这不就正好满足完全背包的条件了吗

    means:给出小猪钱罐的重量和装满钱后的重量,然后是几组数据,每组数据包括每种钱币的价值与重量要求出装满钱罐时的最小价值

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 using namespace std;
     6 const int qq=50000+10;
     7 const int MAX=1e8;
     8 int dp[qq];
     9 int v[qq],p[qq];
    10 int main()
    11 {
    12     int t;scanf("%d",&t);
    13     while(t--){
    14         int a,b;scanf("%d%d",&a,&b);
    15         int c=b-a;
    16         int n;scanf("%d",&n);
    17         for(int i=0;i<n;++i)
    18             scanf("%d%d",&p[i],&v[i]);
    19         for(int i=1;i<=c;++i)
    20             dp[i]=MAX;
    21         dp[0]=0;
    22         for(int i=0;i<n;++i)    
    23             for(int j=v[i];j<=c;++j)
    24                 dp[j]=min(dp[j],dp[j-v[i]]+p[i]);
    25         if(dp[c]==MAX)    printf("This is impossible.
    ");
    26         else            printf("The minimum amount of money in the piggy-bank is %d.
    ",dp[c]);
    27     }
    28     return 0;
    29 } 

    HDU 2191 多重背包问题、

    其实还是应用01背包的思想、不过这里有一个小技巧就是二进制表示法、

    比如 13、可以表示成 1+2+4+5  这4个数可以组成1到13之间的任意一个数、

    那么就可以多重背包拆分成01背包问题、

    千万注意将空间压缩成一维的话是逆序遍历、这里解释一下 dp数组中的每一个值都是一种状态,该种状态在当前是独立的不受其他影响的,如果正序遍历的话前面得到的一些状态影响其他状态的生成、

    - -、我是这么理解的、  总之你要dp的话就是... 唉本弱弱语文水平好差、

    联想一下二维数组下是怎么更新状态的、再看看一维、这样就很容易理解了

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 const int qq=1000;
     7 int p[qq],v[qq];
     8 int dp[qq];
     9 int main()
    10 {
    11     int t;scanf("%d",&t);
    12     while(t--){
    13         int price,kind;
    14         scanf("%d%d",&price,&kind);
    15         int count=0;
    16         int a,b,c;
    17         for(int i=0;i<kind;++i){
    18             scanf("%d%d%d",&a,&b,&c);
    19             int t=1;
    20             while(c>=t){
    21                 p[count]=a*t;
    22                 v[count++]=b*t;
    23                 c=c-t;
    24                 t=t<<1;
    25             }
    26             if(c){
    27                 p[count]=a*c;
    28                 v[count++]=b*c;
    29             }
    30         }
    31         for(int j,i=0;i<count;++i)
    32             for(j=price;j>=p[i];--j)
    33                 dp[j]=max(dp[j],dp[j-p[i]]+v[i]);
    34         printf("%d
    ",dp[price]);
    35         memset(dp,0,sizeof(dp));        //一定记得初始化、毕竟有很多组数据、
    36     }
    37     return 0;
    38 }
  • 相关阅读:
    课程作业3
    课程作业一(改进)
    C语言中的几种常见排序算法
    PADS 导Gerber文件
    时钟信号线上串一小电阻的作用
    Allegro pcb -等长设计
    Allegro PCB -内层分割,比如电源层需要分割几种电源
    Allegro PCB -通孔焊盘制作 及Flash制作
    Allegro PCB -如何做自定义焊盘
    MFC中的NMHDR结构体和NMUPDOWN结构体
  • 原文地址:https://www.cnblogs.com/sasuke-/p/5365454.html
Copyright © 2020-2023  润新知