• poj1015


    题意:n个人,每个人都可以看做有两个参数a,b,从中选m个人,使得ans1=|sigma(a)-sigma(b)|尽可能小,如果存在相等的情况,就保留ans2=sigma(a+b)max。

    dp;

    dp[j][k]表示选第j个人,使得ans1=k时,最大的ans2;

    path[j][k]表示选第j个且ans1=k时的编号//记录路径

    v=a-b;s=a+b;

    dp[j][k+v[i]]=max(dp[j-1][k]+s[i]);if(dp[j-1][k]>=0 && i not in path[j-1][k])

    ************************************************************

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1000;

    int n,m,P,cas=0;
    int a[maxn],b[maxn];
    int v[maxn],s[maxn],ans[maxn];
    int dp[maxn][maxn],path[maxn][maxn];

    void input()
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            v[i]=a[i]-b[i];
            s[i]=a[i]+b[i];
        }
    }

    bool ok(int x,int p,int q)
    {
        while(path[p][q]!=x && p)
        {
            q-=v[path[p][q]];
            p--;
        }
        return p ? 0 : 1;
    }

    void do_dp()
    {
        memset(dp,-1,sizeof(dp));
        memset(path,0,sizeof(path));
        dp[0][P=20*m]=0;
        //printf("P=%d ",P);
        for(int j=1;j<=m;j++)
            for(int k=0;k<=P*2;k++)
                for(int i=1;i<=n;i++)
                    if(dp[j-1][k]>=0 && dp[j][k+v[i]]<dp[j-1][k]+s[i] && ok(i,j-1,k))
                    {
                        dp[j][k+v[i]]=dp[j-1][k]+s[i];
                        path[j][k+v[i]]=i;
                    }
    }

    void output()
    {
        int p=0;
        for(int i=0;i<=P;i++)
            if(dp[m][P+i]>=0 || dp[m][P-i]>=0)
            {
                p = dp[m][P+i] > dp[m][P-i] ? (P+i) : (P-i);
                break;
            }
        //printf("p=%d ",p);
        memset(ans,0,sizeof(ans));
        int tmp=m;
        while(tmp)
        {
            ans[tmp]=path[tmp][p];
            p-=v[path[tmp][p]];
            tmp--;
        }
        sort(ans+1,ans+1+m);
        int ans1=0,ans2=0;
        for(int i=1;i<=m;i++)ans1+=a[ans[i]],ans2+=b[ans[i]];
        printf("Jury #%d ",++cas);
        printf("Best jury has value %d for prosecution and value %d for defence: ",ans1,ans2);
        for(int i=1;i<=m;i++)printf(" %d",ans[i]);
        printf(" ");
    }

    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&m) && (n || m))
        {
            input();
            do_dp();
            output();
        }
        return 0;
    }

    ************************************************************

  • 相关阅读:
    使用GitHub建立自己的个人主页
    学习Linux第二天
    学习Linux第一天
    网页布局基础
    HTML弹出窗口
    CSS进阶
    HTML+CSS入门
    廖老师JavaScript教程高阶函数-sort用法
    获取页面的title值
    if...else...这段代码打印结果,并简述其理由
  • 原文地址:https://www.cnblogs.com/MobileRobot/p/3783496.html
Copyright © 2020-2023  润新知