题意:有n首歌,剩余T秒时间,问在结束之前,使得唱的歌的数目尽量多,在此前提下尽量晚的离开KTV。跟多的细节请读Input
题解:如果不考虑数目,则是一道裸的01背包,而现在是数目多的优先,其次再是时间长的优先。所以适合用一个结构体,注意优先级!!!
然后按照01背包的思想做就是了。。。更新值的时候请注意(不过应该没有人犯我这种错误,还整了3个小时,??)
这次涨知识了,不过有些细节还需要模拟几遍,好好理解一下。加油!!!!
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=10000; 8 struct node{ 9 int time,num; 10 bool operator<(const node& i)const{ 11 if(num==i.num) return time<i.time; 12 return num<i.num; 13 } 14 }dp[maxn]; 15 16 int n,T; 17 int so[55]; 18 19 void solve(int t) 20 { memset(dp,0,sizeof(dp)); 21 for(int i=1;i<=n;i++){ 22 for(int j=T;j>=so[i];j--){ 23 node temp; 24 temp.time=dp[j-so[i]].time+so[i]; 25 temp.num =dp[j-so[i]].num+1; 26 if(dp[j]<temp) dp[j]=temp; 27 } 28 } 29 printf("Case %d: %d %d\n",t,dp[T].num+1,dp[T].time+678); 30 } 31 32 int main() 33 { int kase; 34 cin>>kase; 35 for(int t=1;t<=kase;t++){ 36 cin>>n>>T; 37 int sum=0; 38 for(int i=1;i<=n;i++) { cin>>so[i]; sum+=so[i]; } 39 40 T=min(T-1,sum); //T-1是个小技巧 41 solve(t); 42 } 43 return 0; 44 }
WA了几次的代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=10000; 8 struct node{ 9 int time,num; 10 bool operator<(const node& i)const{ 11 return num<i.num; //对time没定义优先级 12 } 13 }dp[maxn]; 14 15 int n,T; 16 int so[55]; 17 18 void init(){ 19 for(int i=0;i<=T;i++){ 20 dp[i].time=0; 21 dp[i].num=0; 22 } 23 } 24 25 void solve(int t){ 26 init(); 27 28 for(int i=1;i<=n;i++){ 29 for(int j=T;j>=so[i];j--){ 30 dp[j].time=max(dp[j].time,dp[j-so[i]].time+so[i]); //错误的更新方式,大错特错!!!! 31 dp[j].num=max(dp[j].num,dp[j-so[i]].num+1); 32 } 33 } 34 sort(dp,dp+T+1); 35 36 int anst,ans=0; 37 for(int i=T;i>=0;i--) if(dp[i].time!=T) { anst=dp[i].num; break; } 38 for(int i=0;i<=T;i++) if(dp[i].num==anst&&dp[i].time!=T) ans=max(ans,dp[i].time); 39 40 printf("Case %d: %d %d\n",t,anst+1,ans+678); 41 } 42 43 int main() 44 { int cases; 45 cin>>cases; 46 for(int t=1;t<=cases;t++){ 47 cin>>n>>T; 48 int sum=0; 49 for(int i=1;i<=n;i++) { cin>>so[i]; sum+=so[i]; } 50 sort(so+1,so+n+1); 51 52 if(T>sum) printf("Case %d: %d %d\n",t,n+1,sum+678); 53 else if(T==sum) printf("Case %d: %d %d\n",t,n,sum-so[1]+678); 54 else solve(t); 55 } 56 return 0; 57 }
时间: 2024-10-29 08:01:52