老司机wbt又要开车了,焊死车门禁止下车,wbt现在在车内提供了n张电竞死歌wpm的CD唱片,已知wbt开车的时间是n分钟,你该如何去选择唱片去消磨这无聊的时间呢
假设:
- CD数量不超过20张
- 没有一张CD唱片超过 N 分钟
- 每张唱片只能听一次
- 唱片的播放长度为整数
- N 也是整数
我们需要找到最能消磨时间的唱片数量,并按使用顺序输出答案(必须是听完唱片,不能有唱片没听完却到了下车时间的情况发生)
Input
多组输入
每行输入第一个数字N, 代表总时间,第二个数字 M 代表有 M 张唱片,后面紧跟 M 个数字,代表每张唱片的时长 例如样例一: N=5, M=3, 第一张唱片为 1 分钟, 第二张唱片 3 分钟, 第三张 4 分钟
所有数据均满足以下条件:
N≤10000
M≤20
Output
输出所有唱片的时长和总时长,具体输出格式见样例
Sample Input
5 3 1 3 4 10 4 9 8 4 2 20 4 10 5 7 4 90 8 10 23 1 2 3 4 5 7 45 8 4 10 44 43 12 9 8 2
Sample Output
1 4 sum:5 8 2 sum:10 10 5 4 sum:19 10 23 1 2 3 4 5 7 sum:55 4 10 12 9 8 2 sum:45
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<cstring> #include<cstdio> #include<iostream> #include<queue> #include<algorithm> using namespace std; typedef long long ll; template <typename Tp> void read(Tp &x){//read(n); x=0;char ch=1;int fh; while(ch!='-'&&(ch>'9'||ch<'0')){ ch=getchar(); } if(ch=='-'){ fh=-1;ch=getchar(); }else fh=1; while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+ch-'0';ch=getchar(); } x*=fh; } inline char read1()//字符串读入挂 { register char ch=getchar(); while(ch<'A'||ch>'M')ch=getchar(); return ch; } const int maxn=1e3+100; int a[maxn]; int dp[maxn][maxn]; int b[maxn]; int main(){ int n,m; while(cin>>m){ cin>>n; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ dp[i][j]=dp[i-1][j]; if(j>=a[i]){ dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+a[i]); } } } int p=dp[n][m]; int cnt=0; int sum=p; for(int i=n;i>=1;i--){ if(dp[i][sum]==(dp[i-1][sum-a[i]]+a[i])){ sum-=a[i]; b[++cnt]=a[i]; } } for(int i=cnt;i>=1;i--){ cout<<b[i]<<" "; } printf("sum:%d ",p); } }