NC51166. Jury Compromise
描述
输入描述
The input file contains several jury selection rounds. Each round starts with a line containing two integers n and m. n is the number of candidates and m the number of jury members.
These values will satisfy , and of course m<=n. The following n lines contain the two integers pi and di for i = 1,...,n. A blank line separates each round from the next.
The file ends with a round that has n = m = 0.
输出描述
For each round output a line containing the number of the jury selection round ('Jury #1', 'Jury #2', etc.).
On the next line print the values D(J ) and P (J ) of your jury as shown below and on another line print the numbers of the m chosen candidates in ascending order. Output a blank before each individual candidate number.
Output an empty line after each test case.
示例1
输入:
4 2 1 2 2 3 4 1 6 2 0 0
输出:
Jury #1 Best jury has value 6 for prosecution and value 4 for defence: 2 3
C++14(g++5.4) 解法, 执行用时: 77ms, 内存消耗: 17680K, 提交时间: 2019-11-14 07:36:01
#include <cstring> #include <algorithm> #include <iostream> #include <cstdio> #include <cmath> #include <vector> #define ll long long #define rep(i,a,b) for(int i=(a);i<=(b);++i) using namespace std; const int M=205; vector <int> path; int m,n,f[25][1005],d[M][25][1005],a[M],b[M],T,sum1,sum2,ans; void get_path(int i,int j,int k) { if(j==0) return ; int ls=d[i][j][k]; get_path(ls-1,j-1,k-(a[ls]-b[ls])); path.push_back(ls); sum1+=a[ls];sum2+=b[ls]; } int main() { while(cin>>n>>m&&n) { memset(f,0xcf,sizeof f); rep(i,1,n) scanf("%d%d",&a[i],&b[i]); f[0][400]=0;//平移! rep(i,1,n) { rep(j,0,m) rep(k,0,800) d[i][j][k]=d[i-1][j][k]; for(int j=m;j>=1;--j) rep(k,0,800) { if(k-(a[i]-b[i])<0||k-(a[i]-b[i])>800) continue; if(f[j][k]<f[j-1][k-(a[i]-b[i])]+a[i]+b[i]) { f[j][k]=f[j-1][k-(a[i]-b[i])]+a[i]+b[i]; d[i][j][k]=i; } } } ans=0; rep(k,0,400) { if(f[m][400+k]>=0&&f[m][400+k]>=f[m][400-k]) { ans=400+k; break; } if(f[m][400-k]>=0) { ans=400-k; break; } } sum1=0;sum2=0; path.clear(); get_path(n,m,ans); printf("Jury #%d\n", ++T); printf("Best jury has value %d for prosecution and value %d for defence:\n",sum1,sum2); for (int i=0;i<path.size();++i) printf(" %d",path[i]); printf("\n\n"); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 34ms, 内存消耗: 1760K, 提交时间: 2020-04-01 23:17:32
#include<bits/stdc++.h> using namespace std; struct node { int a,b; }q[205]; int dp[25][855]; vector <int> ans[25][855];int d1=0,p1=0; int main() { int n,m,cnt=1; while(~scanf("%d%d",&n,&m)){ if(n==m&&n==0) break; for(int i=1;i<=n;i++){ scanf("%d%d",&q[i].a,&q[i].b); } memset(dp,-1,sizeof dp); for(int i=1;i<=m;i++) for(int j=0;j<=m*40;j++) ans[i][j].clear(); int mi=1e9;dp[0][20*m]=0; for(int i=1;i<=n;i++){ int d=q[i].a-q[i].b,t=q[i].a+q[i].b; for(int h=m;h>=1;h--) for(int j=0;j<40*m;j++) if(dp[h-1][j]!=-1) if(dp[h][j+d]<dp[h-1][j]+t){ dp[h][j+d]=dp[h-1][j]+t; ans[h][j+d]=ans[h-1][j]; ans[h][j+d].push_back(i); } } for(int i=0;;i++){ if(dp[m][20*m-i]!=-1||dp[m][20*m+i]!=-1){ mi=i;break; } } mi=dp[m][mi+m*20]>dp[m][m*20-mi]?mi:-mi; printf("Jury #%d\n",cnt++); d1=dp[m][mi+m*20]+mi;d1/=2; p1=dp[m][mi+m*20]-mi;p1/=2; printf("Best jury has value %d for prosecution and value %d for defence:\n",d1,p1); for(int i=0;i<m;i++) printf("%d ",ans[m][mi+m*20][i]);printf("\n\n"); } }