poj 1015Jury Compromise

来源:互联网 发布:sql 逻辑运算符 编辑:程序博客网 时间:2024/06/05 08:06

这个题目真的困扰了对于还是新手的我2个小时以上 首先状态转移方程还是很好找的 通过数据范围一下就看出来了 直接拿差值当作其中的状态参数

dp[i][j]表示选择了i个物品 差值为j的时候的最大的和 并且有path[i][j]纪录前驱元素 然后dp就可以了 

注意有几点 1. j有正有负 所以要对他进行平移;

 2. 其中选择每一个物品的时候 一定要有一个函数判断之前的状态有没有重复 这个直接判重是不行的 要走一遍看看;

这个函数的写法很关键 我感觉以后也很有用的说。

#include <iostream>#include <algorithm>#include <stdlib.h>#include <string>#include <string.h>#include <stdio.h>#include <ctype.h>#include <sstream>#include <ostream>#include <cmath>#include <stack>#include <queue>#include <list>#define pi acos(-1)#define e exp(1)#define inf 0x3f3f3f3fusing namespace std;int dp[30][1000];int path[30][1000];int k[300];int b[300];int arr[300];int check(int i,int j){    if(j>=1000||j<0||dp[i][j]==-1) return 0;    return 1;}int tracepath(int i,int j,int q)//追踪前面的选择 来进行判重{    int start=path[i][j];    while(i!=0)    {        if(start==q) return 0;        i--;        j=j-k[start]+b[start];        start=path[i][j];    }    return 1;}int main(){    int n,m;int t=1;    while(scanf("%d %d",&n,&m)!=EOF&&(n||m))    {        memset(dp,-1,sizeof(dp));        memset(path,-1,sizeof(path));        dp[0][500]=0;        for(int i=1;i<=n;i++)            scanf("%d %d",&k[i],&b[i]);      for(int i=1;i<=m;i++)        {        for(int j=0;j<1000;j++)            {                for(int q=1;q<=n;q++)                {                    if(check(i-1,j-(k[q]-b[q])))                    {                        if(dp[i-1][j-(k[q]-b[q])]+k[q]+b[q]>dp[i][j]&&tracepath(i-1,j-k[q]+b[q],q))                        {                             dp[i][j]=dp[i-1][j-k[q]+b[q]]+k[q]+b[q];                             path[i][j]=q;                        }                    }                }            }        }        int rout=0;int minus=1;        for(int i=0;i<=499;i++)        {             if(dp[m][500+i]==-1&&dp[m][500-i]!=-1)             {                 rout=500-i;                 minus=i;                 break;             }             else if(dp[m][500-i]==-1&&dp[m][500+i]!=-1)             {                 rout=500+i;                 minus=i;                 break;             }             else if(dp[m][500-i]!=-1&&dp[m][500+i]!=-1)             {                 if(dp[m][500+i]>dp[m][500-i]) {rout=500+i;minus=i;}                 else rout=500-i;                 break;             }             else continue;        }        int start=path[m][rout];        stack<int> s;        while(m!=0) {            s.push(start);            --m;            rout=rout-k[start]+b[start];            start=path[m][rout];        }        int ss=0;        while(!s.empty())        {            arr[ss++]=s.top();            s.pop();        }        sort(arr,arr+ss);        int p=0;int d=0;        for(int i=0;i<ss;i++) { p+=k[arr[i]];d+=b[arr[i]];}        printf("Jury #%d\n",t++);        printf("Best jury has value %d for prosecution and value %d for defence:\n",p,d);        for(int i=0;i<ss;i++) printf(" %d",arr[i]);        printf("\n\n");            }    return 0;}

0 0
原创粉丝点击