tyvj P1005 采药

来源:互联网 发布:媒体推广是seo 编辑:程序博客网 时间:2024/06/05 04:43
-题目来源:

题目描述:

描述

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

输入格式

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

输出格式

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

测试样例1

输入

70 3 71 100 69 1 1 2

输出

3

备注

对于30%的数据,M <= 10;对于全部的数据,M <= 100。
-------------------------------------------------------------------------------------------------------------------------------------
思路:这个问题属于背包问题,更进一步讲是0-1问题。
一开始我尝试使用价值/时间最大法,即将所有药材都以 价值/时间 降序排列,从 价值/时间 最大的开始塞进背包直到超出时间。这种方法的确能够通过样例,但是这个样例实在太简单了,没有暴露出其他问题,所以没有AC,于是将原题目百度了一下,发现要使用动态规划的方法。(可见:http://wenku.baidu.com/link?url=SDqMRJ5bPrTPn3P-Nx3dpao2nVqvPiiBghk8qd5CMtDVFp5CWdOSBkrKgpHdStWB7vHPFSU_o3qSBknCh_boul2TXH1vT8ZJhsAy2roEUtq)
关键的动态规划要点我总结如下:
1、把所有的草药从上到下排成1列,从1开始升序编号。
2、采药的终极目标是使到最后的价值最大,那么我们可以求对每一株的最大价值来获得最后的最大价值。
3、两个重要推论:(来自分析和解答)
4、

Y

w

j

>

)

,

1

(

)

,

(

Y

j

A

Y

j

A

=

若wj>Y,则A(j,Y)=A(j-1,Y)。也就是说,如果采这药材的时间超过最长时间,那么到这个药材的最大价值等于前一个药材的最大价值。
5、若wj<Y,则A(j,Y)=max(A(j-1,Y),A(j-1,Y-wj)+pj).这就是说,如果采这个药材的时间没有超过最长时间,那么这株药材的最大价值时间就是前一个药材并且在Y减去该药材所需时间后的局限时间里的最大价值。
6、开二维数组 int Gather[M+1][T+1],Gather[i][j]的值表示总的采药时间不超过j,采药数量不超过i时所采草药的最大价值。
然后以下图的顺序开始遍历
_______________________________________________________________________________________________________________________________________________________
知道思路之后,会遇到一些代码编写上的小问题。(我用的是C)
要注意到Gather二维数组的是以[数量][时间]为坐标的,这和输入数据不同,容易搞混;
其次,Gather二维数组的标度比真正的标度要大1,所以Array数组中会出现i-1的情况。
AC代码如下:
#include <stdio h=""></stdio>
#include <stdio h=""><pre name="code" class="cpp">#include <stdlib.h>void Package(int T,int M);int Max(int A,int B);int Array[100][2];int Gather[101][1001];int main(){int M,T;int Time, Result;int i;scanf("%d%d",&T,&M);for(i = 0;i < M;i++){scanf("%d%d",&Array[i][0],&Array[i][1]);}Time=0;Result=0;Package(T,M);printf("%d\n",Gather[M][T]);//system("pause");return 0;}void Package(int T,int M){int i,j;int a,b;for(i=0;i<T+1;i++)Gather[0][i]=0;for(i=0;i<M+1;i++)Gather[i][0]=0;for(i = 1;i < T+1;i++)for(j = 1;j < M+1;j++){if(Array[j-1][0]>i)Gather[j][i]=Gather[j-1][i];else{Gather[j][i]=Max(Gather[j-1][i],Gather[j-1][i-Array[j-1][0]]+Array[j-1][1]);}/*for(a = 0; a < M+1; a++){for(b = 0; b <T+1;b++)printf("%2d",Gather[a][b]);printf("\n");}printf("__________________________\n");*/}}int Max(int A,int B){return (A>B)?A:B;}





0 0
原创粉丝点击