洛谷 P1833【樱花】
题目背景
《爱与愁的故事第四弹·plant》第一章。
题目描述
爱与愁大神后院里种了n棵樱花树,每棵都有美学值Ci。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:一种樱花树看一遍过,一种樱花树最多看Ai遍,一种樱花树可以看无数遍。但是看每棵樱花树都有一定的时间Ti。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学。
输入输出格式
输入格式:
共n+1行:
第1行:三个数:现在时间Ts(几点:几分),去上学的时间Te(几点:几分),爱与愁大神院子里有几棵樱花树n。
第2行~第n+1行:每行三个数:看完第i棵树的耗费时间Ti,第i棵树的美学值Ci,看第i棵树的次数Pi(Pi=0表示无数次,Pi是其他数字表示最多可看的次数Pi)。
输出格式:
只有一个整数,表示最大美学值。
输入输出样例
输入样例#1:
6:50 7:00 3 2 1 0 3 3 1 4 5 4
输出样例#1:
11
解题思路
咳咳,这是一道典型的混合背包,对于混合背包呢,我们只需要做个判断,然后分别装包就行了啦......还有一个就是时间的读入,记得转换哦
题解
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 int t[10005],v[10005],p[10005]; 5 int dp[100005]; 6 int T()//时间转换(有点麻烦,所以我之后给大家介绍更简单的) 7 { 8 int sum=0; 9 int S=0,E=0,ss=0,ee=0; 10 bool flag=true; 11 string s,e; 12 cin>>s>>e; 13 for(int i=0;i<s.size();i++) 14 { 15 if(s[i]!=':'&&flag) 16 { 17 S=S*10+(s[i]-'0'); 18 } 19 else if(s[i]==':') 20 { 21 flag=false; 22 continue; 23 } 24 else ss=ss*10+(s[i]-'0'); 25 } 26 flag=true; 27 for(int i=0;i<e.size();i++) 28 { 29 if(e[i]!=':'&&flag) 30 { 31 E=E*10+(e[i]-'0'); 32 } 33 else if(e[i]==':') 34 { 35 flag=false; 36 continue; 37 } 38 else ee=ee*10+(e[i]-'0'); 39 } 40 sum=(E-S)*60+ee-ss; 41 return sum; 42 } 43 int main() 44 { 45 int time=T(); 46 cin>>n; 47 for(int i=1;i<=n;i++) 48 { 49 scanf("%d%d%d",&t[i],&v[i],&p[i]); 50 if(p[i]==0)//完全背包 51 { 52 for(int j=t[i];j<=time;j++) 53 dp[j]=max(dp[j],dp[j-t[i]]+v[i]); 54 } 55 else//我们多重背包和01背包可以一起做操作 56 { 57 int num=min(p[i],time/t[i]); 58 for(int k=1;num>0;k<<=1) 59 { 60 if(k>num)k=num; 61 num-=k; 62 for(int j=time;j>=t[i]*k;j--) 63 dp[j]=max(dp[j],dp[j-t[i]*k]+v[i]*k); 64 } 65 } 66 } 67 cout<<dp[time];//输出就好 68 }
时间转换优化
int T() { int a1,a2,a3,a4; scanf("%d:%d%d:%d",&a1,&a2,&a3,&a4); int sum=(a3-a1)*60; sum=sum+a4-a2; return sum; }