zoukankan      html  css  js  c++  java
  • 19 采药 dp-2

    Description

    辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 
    
    如果你是辰辰,你能完成这个任务吗?

    Input

    输入的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的的整数,分别表示采摘某株草药的时间和这株草药的价值。 
    
    
    
    

    Output

    输出只包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

    Sample Input

    70 3
    71 100
    69 1
    1 2
    

    Sample Output

    3
     1 #include<iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 int main()
     6 {
     7     int t,m;//总共能够用来采药的时间t,山洞里的草药的数目m
     8     int data[1005][2],ans[1005];//采摘某株草药的时间和这株草药的价值
     9     while(cin>>t>>m)
    10     {
    11         for(int i=0;i<m;i++)
    12         cin>>data[i][0]>>data[i][1];//输入采摘某株草药的时间和这株草药的价值
    13         memset(ans,0,sizeof(ans));//初始化数组
    14         for(int i=0;i<m;i++)
    15         {
    16             for(int j=t;j>=1;j--)
    17             {
    18                 if(j-data[i][0]>=0)
    19                 ans[j]=max(ans[j],ans[j-data[i][0]]+data[i][1]);
    20                 /*解释一下:
    21 
    22                 假设最大容量t=10,物品个数m=3,采摘药用时w{3,4,5},药物价值p{4,5,6}。
    23 
    24                 当进行第i次循环时,f[v]中保存的是上次循环产生的结果,
    25                 即第i-1次循环的结果(i>=1)。
    26                 所以f[v]=max{f[v],f[v-w[i]]+p[i]}这个式子中,
    27                 等号右边的f[v]和f[v-w[i]]+p[i]都是前一次循环产生的值。*/
    28             }
    29         }
    30         sort(ans,ans+t+1);
    31         cout<<ans[t]<<endl;
    32     }
    33     return 0;
    34 }
    View Code

    初始化的细节问题:

     在求最优解的背包问题中,一般有两种不同的问法:1、要求“恰好装满背包”时的最优解;2、求小于等于背包容量的最优解,即不一定恰好装满背包。

    这两种问法,在初始化的时候是不同的。

    1、要求“恰好装满背包”时的最优解:

    在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。如果不能恰好满足背包容量,即不能得到f[V]的最优值,则此时f[V]=-∞,这样就能表示没有找到恰好满足背包容量的最优值。

    2、求小于等于背包容量的最优解,即不一定恰好装满背包:

    如果并没有要求必须把背包装满,而是只希望价值尽量大,初始化时应该将f[0..V]全部设为0。

    总结

    01背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另外,别的类型的背包问题往往也可以转换成01背包问题求解。故一定要仔细体会上面基本思路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。

    参考:

    http://www.cnblogs.com/fly1988happy/archive/2011/12/13/2285377.html

    http://blog.sina.com.cn/s/blog_4cd99cfa0100mer2.html

    http://www.cnblogs.com/tanky_woo/archive/2010/07/31/1789621.html

  • 相关阅读:
    公用表表达式(CTE)的递归调用
    c# 如何让tooltip显示文字换行
    实战 SQL Server 2008 数据库误删除数据的恢复
    SQL SERVER数据库中 是否可以对视图进行修改删除
    asp.net中实现文件批量上传
    sql server 2008学习2 文件和文件组
    sql server 2008学习3 表组织和索引组织
    sql server 2008学习4 设计索引的建议
    sql server 2008学习10 存储过程
    .net 调用 sql server 自定义函数,并输出返回值
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/5375516.html
Copyright © 2011-2022 走看看