【问题描述】
辉夜是个天资聪颖的少女,她的梦想是成为世界上最伟大的医师。为此,她想拜附近
最有威望的医师永琳为师。永琳为了判断她的资质,给她出了一个难题。永琳把她带到一
个到处都是草药的山洞里对她说:“孩子,这个山洞里有一些不同的草药,采每一株都
需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可
以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辉夜,你能完成这个任务吗?
【输入文件】
输入文件medic.in的第一行有两个整数T和M,用一个空格隔开,T代表总共能够用来
采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个整数,分别表示
采摘某株草药的时间和这株草药的价值。
【输出文件】
输出文件medic.out包括一行,这一行只包含一个整数,表示在规定的时间内,可以采
到的草药的最大总价值。如果不能完成这个任务输出“不能”。
参考代码是:
1 #include<cstdio>
2 using namespace std;
3 int main()
4 {
5 printf("不能");
6 return 0;
7 }
啊,当然不是。
这个题有两种数据范围,分别对应两种代码
第一种:
1 <= T <= 1000
1 <= M <= 100
对于30%的数据,M <= 10;
对于全部的数据,M <= 100。
这个呢就是动态规划做01背包,非常简单
1 #include<cstdio> 2 using namespace std; 3 int v,p,T,M,dp[1005]; 4 int main() 5 { 6 freopen ("medic.in","r",stdin); 7 freopen ("medic.out","w",stdout); 8 scanf("%d%d",&T,&M); 9 for (int i=1;i<=M;i++) 10 { 11 scanf("%d%d",&v,&p); 12 for (int j=T;j>=v;j--) 13 dp[j]=max(dp[j],dp[j-v]+p); //递推式子,j是剩余时间 14 } 15 printf("%d",dp[T]); 16 return 0; 17 }
总体来说背包的递推通式就是:
1 f[j] = max(f[j],f[j-v[i]]+w[i])
当然这是数据范围比较小的情况……
第二种:
50%的数据中 T,M ≤ 1000;
100%的数据中 T,M ≤ 100000,Ti,Vi ≤10。
这个需要加上奇奇怪怪的优化
我不会
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <string> 5 #include <stdlib.h> 6 #include <vector> 7 #include <algorithm> 8 #include <math.h> 9 using namespace std; 10 const int MAXN=100050; 11 int box[11][11],dp[MAXN],N,M,t1,t2,er[25],ge[20]; 12 void solve(int v,int p,int n); 13 void solve(int v,int p,int n) 14 { 15 int t=n,time=0,v1,p1; 16 memset(ge,0,sizeof(ge)); 17 for (int i=1;i<=20;i++) 18 { 19 if (t-er[i]>=0) 20 { 21 ge[i]=er[i]; 22 t-=er[i]; 23 time=i; 24 } 25 else 26 { 27 ge[i]=t; 28 time=i; 29 break; 30 } 31 } 32 for (int i=1;i<=time;i++) 33 { 34 v1=ge[i]*v; 35 p1=ge[i]*p; 36 for (int j=M;j>=v1;j--) 37 dp[j]=max(dp[j],dp[j-v1]+p1); //递推式子 38 } 39 } 40 int main() 41 { 42 freopen ("medic2.in","r",stdin); 43 freopen ("medic2.out","w",stdout); 44 scanf("%d%d",&N,&M); 45 er[1]=1; 46 for (int i=2;i<=20;i++) 47 er[i]=er[i-1]<<1; 48 for (int i=1;i<=N;i++) 49 { 50 scanf("%d%d",&t1,&t2); 51 box[t1][t2]++; 52 } 53 54 for (int i=1;i<=10;i++) 55 { 56 for (int j=1;j<=10;j++) 57 if (box[i][j]) 58 solve(i,j,box[i][j]); 59 } 60 printf("%d ",dp[M]); 61 // cout<<dp[M]<<endl; 62 // solve(1,2,box[1][2]); 63 return 0; 64 }
啊gg让我们写题解可是我不想写