• POJ 1015 Jury Compromise


    感觉此题略难。。。。。。

    背包问题。据说有一种二维DP的写法是错的。亲测,背包做法无误。

    dp[i][j][k]表示前i个物品,选择j个,差值为k的情况下获得的最大总和

    dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-1][k-差]+和) 即第i个物品用或者不用。

    DP完成之后,在表中寻找一下最优解即可。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<string>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct Path
    {
      //  int a,b,c;
        int w;
    } path[200+20][20+20][1000+20];
    int dp[200+20][20+20][1000+20];
    int p[200+20],d[200+20];
    int n,m;
    stack<int>S;
    int Z=400;
    
    int main()
    {
        int Case=1;
        while(~scanf("%d%d",&n,&m))
        {
            if(!n&&!m) break;
    
            for(int i=1; i<=n; i++) scanf("%d%d",&p[i],&d[i]);
            memset(dp,-1,sizeof dp);
            dp[0][0][Z]=0;
    
            for(int i=0; i<=n; i++)
                for(int j=0; j<=m; j++)
                    for(int k=0; k<=2*Z; k++)
                        path[i][j][k].w=-1;
    
            for(int i=1; i<=n; i++)
            {
                for(int j=0; j<=m; j++)
                {
                    for(int k=Z*2; k-(p[i]-d[i])>=0; k--)
                    {
                        if(dp[i-1][j][k]!=-1)
                        {
                            dp[i][j][k]=dp[i-1][j][k];
                            path[i][j][k].w=0;
                        }
    
                        if(j>=1&&dp[i-1][j-1][k-(p[i]-d[i])]!=-1)
                        {
                            if(dp[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i]>dp[i][j][k])
                            {
                                dp[i][j][k]=dp[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i];
                                path[i][j][k].w=1;
                            }
                        }
                    }
                }
            }
    
            int posa,posb,posc;
            int Max=-1;
            for(int i=0; i<=Z; i++)
            {
                for(int j=1; j<=n; j++)
                    if(dp[j][m][Z+i]>Max&&path[j][m][Z+i].w==1)
                        Max=dp[j][m][Z+i],posa=j,posb=m,posc=Z+i;
                for(int j=1; j<=n; j++)
                    if(dp[j][m][Z-i]>Max&&path[j][m][Z-i].w==1)
                        Max=dp[j][m][Z-i],posa=j,posb=m,posc=Z-i;
                if(Max!=-1) break;
            }
    
            while(!S.empty()) S.pop();
    
            int ans1,ans2;
            ans1=(posc-Z+dp[posa][posb][posc])/2;
            ans2=ans1-(posc-Z);
    
            while(1)
            {
                if(path[posa][posb][posc].w==-1) break;
                if(path[posa][posb][posc].w!=-1)
                {
                    int Newa,Newb,Newc;
                    if(path[posa][posb][posc].w==1)
                    {
                        S.push(posa);
                        Newa=posa-1;
                        Newb=posb-1;
                        Newc=posc-(p[posa]-d[posa]);
                    }
                    else
                    {
                        Newa=posa-1;
                        Newb=posb;
                        Newc=posc;
                    }
                    posa=Newa;
                    posb=Newb;
                    posc=Newc;
                }
            }
    
            printf("Jury #%d
    ",Case++);
            printf("Best jury has value %d for prosecution and value %d for defence:
    ",ans1,ans2);
            while(!S.empty())
            {
                printf(" %d",S.top());
                S.pop();
            }
            printf("
    
    ");
    
        }
        return 0;
    }
  • 相关阅读:
    Node.js EventEmitter
    Node.js 事件循环
    Node.js 回调函数(阻塞与非阻塞)
    Node.js REPL(交互式解释器)
    NPM使用介绍
    H5表单验证特性(杂七杂八知识点)
    HTML5存储之indexedDB
    本地存储localStorage和sessionStorage
    高德地图API实例--移动端婚礼请帖
    高德地图API之DOM事件+自定义事件
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5149092.html
Copyright © 2020-2023  润新知