kkksc03考前临时抱佛脚
题目链接 https://www.luogu.com.cn/problem/P2392
其实这个题之前做过但是找题的时候瞄了一眼发现好像不太会了就…当复习了…
话说你个kkkcs03平时能不能学学习,非要临时抱佛脚,给别人找麻烦。
此题有两个状态,一是加在左脑,一是加在右脑,所以是01背包问题。
那么,将一边的脑子加到最接近一半,则另一边脑子所用的时间就是正解。
思路放进代码里写吧。
放AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 ios::sync_with_stdio(false);//快读 6 int a[5],homework[30],dp[30][2000];//开大点儿总没问题 7 //sum为一门科目所有题目所需的时间和 8 //t为左右脑同时开工时一个科目在某个脑子中需要的时间 9 //ans为所有科目需要的最短时间和 10 int sum=0,t=0,ans=0; 11 for(int i=1;i<=4;i++) 12 cin>>a[i]; 13 for(int i=1;i<=4;i++) 14 { 15 t=0; sum=0;//因为要换科目,所以所有题目的时间和(sum)赋为0,t同理 16 for(register int j=1;j<=a[i];j++) 17 { 18 cin>>homework[j]; 19 sum+=homework[j]; 20 } 21 sort(homework,homework+a[i]);//对某一科目所有题目所需时间排序 22 for(register int j=1;j<=a[i];j++) 23 { 24 for(register int k=0;k<=sum/2;k++) 25 { 26 dp[j][k]=dp[j-1][k]; 27 if(homework[j]<=k) 28 dp[j][k]=max(dp[j][k],dp[j-1][k-homework[j]]+homework[j]);//01背包 29 t=max(dp[j][k],t);//一个科目用的时间 30 } 31 } 32 ans+=max(t,sum-t);//累加每个科目所用的最短时间,假设左脑用t时间,则右脑用sum-t时间,取较大值 33 } 34 cout<<ans; 35 return 0; 36 }
然后还有个滚动数组的
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int a[5],homework[21],dp[100010]; 6 int sum=0,t=0; 7 for(int i=1;i<=4;i++) 8 cin>>a[i]; 9 for(int i=1;i<=4;i++) 10 { 11 sum=0; 12 for(register int j=1;j<=a[i];j++) 13 { 14 cin>>homework[j]; 15 sum+=homework[j]; 16 } 17 for(register int j=1;j<=a[i];j++) 18 for(register int k=sum/2;k>=homework[j];k--) 19 dp[k]=max(dp[k],dp[k-homework[j]]+homework[j]); 20 t+=sum-dp[sum/2]; 21 for(register int j=1;j<=sum/2;j++) 22 dp[j]=0;//全部清零为计算下一科目做准备 23 } 24 cout<<t; 25 return 0; 26 }
呼~