二分,排序,贪心。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-6; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } } const int maxn=100010; struct X { int v,w;}s[maxn]; int n,k,ans[maxn]; struct XX {double num; int id;}t[maxn]; double Max; bool cmp(XX a,XX b){ return a.num>b.num; } bool check(double x) { for(int i=1;i<=n;i++) { t[i].num=1.0*s[i].v-x*s[i].w; t[i].id=i; } sort(t+1,t+1+n,cmp); double sum=0; for(int i=1;i<=k;i++) sum=sum+t[i].num; if(sum+eps>=0) { for(int i=1;i<=k;i++) ans[i]=t[i].id; return 1; } return 0; } int main() { while(~scanf("%d%d",&n,&k)) { for(int i=1;i<=n;i++) scanf("%d%d",&s[i].v,&s[i].w); double L=0.0,R=10000000.0; int t=50; while(t--) { double mid=(L+R)/2; if(check(mid)) L=mid; else R=mid; } for(int i=1;i<=k;i++) { printf("%d",ans[i]); if(i<k) printf(" "); else printf("\n"); } } return 0; }
原文:http://www.cnblogs.com/zufezzt/p/5831586.html