zoukankan      html  css  js  c++  java
  • POJ 2976 Dropping tests 01分数规划

    给出n(n<=1000)个考试的成绩ai和满分bi,要求去掉k个考试成绩,使得剩下的∑ai/∑bi*100最大并输出。

    典型的01分数规划

    要使∑ai/∑bi最大,不妨设ans=∑ai/∑bi,则∑ai-ans*∑bi=0。

    设f[ans]=∑ai-ans*∑bi,我们要求一个ans的最大值,使得存在一组解,满足f[ans]=0,而其他的任意解都有f[ans]<=0(如果f[ans]>0,说明∑ai/∑bi>ans,即还有比ans更优的解),对于∑ai/∑bi,从0~1二分枚举答案,对于每一个枚举到的答案mid,如果f[mid]的最大值>0,则说明存在更大的ans,从mid~r里边进一步找更优的解。否则从l~mid中找。

    如何求f[mid]的最大值,f[ans]=∑ai-ans*∑bi=∑(ai-ans*bi) 

    显然如果mid确定了,那么对于每个考试,ai-mid*bi的值也就确定,那么从大到小排序,取最大的n-m个数进行累加即可。

    二分答案法 94MS

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<set>
     7 #include<map>
     8 #include<stack>
     9 #include<vector>
    10 #include<queue>
    11 #include<string>
    12 #include<sstream>
    13 #define eps 1e-9
    14 #define ALL(x) x.begin(),x.end()
    15 #define INS(x) inserter(x,x.begin())
    16 #define FOR(i,j,k) for(int i=j;i<=k;i++)
    17 using namespace std;
    18 typedef long long LL;
    19 int i,j,k,n,m,x,y,T,ans,big,cas,a[1005],b[1005];
    20 bool flag;
    21 double dp[1005],d[1005];
    22 double run(double u)
    23 {
    24     double cur=0;
    25     for (int i=1;i<=n;i++) d[i]=a[i]-u*b[i];
    26     sort(d+1,d+1+n);
    27     for (i=m+1;i<=n;i++) cur+=d[i];
    28     return cur;
    29 }
    30     
    31 int main()
    32 {
    33     while (scanf("%d%d",&n,&m),n+m)
    34     {
    35         for (i=1;i<=n;i++) scanf("%d",&a[i]);
    36         for (i=1;i<=n;i++) scanf("%d",&b[i]);
    37         double l=0,r=1;
    38         while (r-l>eps)
    39         {
    40             double mid=(l+r)/2;
    41             if (run(mid)>0) l=mid;
    42             else r=mid;
    43         }
    44         printf("%d
    ",(int)(r*100+0.5));
    45     }
    46     return 0;
    47 }
    View Code

    Dinkelbach算法(牛顿迭代法) 32MS

    事先随意确定一个数,然后逼近正确答案。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<set>
     7 #include<map>
     8 #include<stack>
     9 #include<vector>
    10 #include<queue>
    11 #include<string>
    12 #include<sstream>
    13 #define eps 1e-9
    14 #define ALL(x) x.begin(),x.end()
    15 #define INS(x) inserter(x,x.begin())
    16 #define FOR(i,j,k) for(int i=j;i<=k;i++)
    17 using namespace std;
    18 typedef long long LL;
    19 struct node
    20 {
    21     double num;
    22     int i;
    23 }d[1005];
    24 int i,j,k,n,m,x,y,T,big,cas,a[1005],b[1005];
    25 bool flag;
    26 double l,ans;
    27 LL p,q; 
    28 bool cmp(node a,node b)
    29 {
    30     return a.num<b.num;
    31 }
    32 int main()
    33 {
    34     while (scanf("%d%d",&n,&m),n+m)
    35     {
    36         for (i=1;i<=n;i++) scanf("%d",&a[i]);
    37         for (i=1;i<=n;i++) scanf("%d",&b[i]);
    38         l=1;ans=0;
    39         while (fabs(l-ans)>eps)
    40         {
    41             ans=l;
    42             for (i=1;i<=n;i++) 
    43             {
    44                 d[i].num=a[i]*1.0-l*b[i];
    45                 d[i].i=i;
    46             }
    47             sort(d+1,d+1+n,cmp);
    48             p=q=0;
    49             for (i=m+1;i<=n;i++)
    50             {
    51                 p+=a[d[i].i];
    52                 q+=b[d[i].i];
    53             }
    54             l=p*1.0/q;
    55         }
    56         printf("%d
    ",(int)(ans*100+0.5));
    57     }
    58     return 0;
    59 }
    View Code

    注意Dinkelbach算法中p,q要使用long long

  • 相关阅读:
    QPBOC扩展应用交易流程
    探索Oracle之数据库升级七 11gR2 to 12c 升级完毕后插入PDB
    Java 存储和读取 oracle CLOB 类型字段的实用方法
    Java读取property配置文件
    AOP (面向切面编程)
    OJB
    JDO
    toplink
    JPA
    ORM
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4113682.html
Copyright © 2011-2022 走看看