一道很经典的DP,状态转移方程为:f[i,j,k]=max{f[i-1,j,k],f[i-1,j-1,k-(p[i]-d[i])]+p[i]+d[i]}。其中f[i,j,k]表示在前i个候选人中选择j个人,并且辩控差为k时的最大辩控和。另外用path[i,j,k]来记录路径,表示当前方案下选择的最后一个人。详细见代码:
 #include<iostream>
#include<iostream>
 #include<stack>
#include<stack>
 using namespace std;
using namespace std;
 int n,m,test;
int n,m,test;
 int p[205],d[205];
int p[205],d[205];
 int f[205][25][805];
int f[205][25][805];
 int path[205][25][805];
int path[205][25][805];
 int main()
int main()


 {
{
 test=0;
    test=0;
 while(scanf("%d%d",&n,&m)!=EOF&&(m||n))
    while(scanf("%d%d",&n,&m)!=EOF&&(m||n))

 
     {
{
 int i,j,k;
        int i,j,k;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)
 scanf("%d%d",&p[i],&d[i]);
            scanf("%d%d",&p[i],&d[i]);
 int mid=m*20;
        int mid=m*20;
 memset(f,-1,sizeof(f));
        memset(f,-1,sizeof(f));
 memset(path,-1,sizeof(path));
        memset(path,-1,sizeof(path));
 for(i=0;i<=n;i++) f[i][0][mid]=0;
        for(i=0;i<=n;i++) f[i][0][mid]=0;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)
 for(j=1;j<=m&&j<=i;j++)
            for(j=1;j<=m&&j<=i;j++)
 for(k=0;k<=2*mid;k++)
                for(k=0;k<=2*mid;k++)

 
                 {
{
 f[i][j][k]=f[i-1][j][k];
                    f[i][j][k]=f[i-1][j][k];
 path[i][j][k]=path[i-1][j][k];
                    path[i][j][k]=path[i-1][j][k];
 if(k>=p[i]-d[i]&&k-(p[i]-d[i])<=2*mid
                    if(k>=p[i]-d[i]&&k-(p[i]-d[i])<=2*mid
 &&f[i-1][j-1][k-(p[i]-d[i])]!=-1
                        &&f[i-1][j-1][k-(p[i]-d[i])]!=-1
 &&f[i][j][k]<=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i])
                        &&f[i][j][k]<=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i])

 
                     {
{
 f[i][j][k]=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i];
                        f[i][j][k]=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i];
 path[i][j][k]=i;
                        path[i][j][k]=i;
 }
                    }
 }
                }
 i=0;
        i=0;
 int conc;
        int conc;
 while(i<=mid)
        while(i<=mid)

 
         {
{
 if(f[n][m][mid+i]!=-1||f[n][m][mid-i]!=-1)
            if(f[n][m][mid+i]!=-1||f[n][m][mid-i]!=-1)
 break;
                break;
 i++;
            i++;
 }
        }
 if(f[n][m][mid+i]>f[n][m][mid-i])
        if(f[n][m][mid+i]>f[n][m][mid-i])
 conc=mid+i;
            conc=mid+i;
 else conc=mid-i;
        else conc=mid-i;
 int prose=0,def=0;
        int prose=0,def=0;
 stack<int> ss;
        stack<int> ss;
 i=path[n][m][conc];
        i=path[n][m][conc];
 j=m;
        j=m;
 while(i!=-1)
        while(i!=-1)

 
         {
{
 prose+=p[i];
            prose+=p[i];
 def+=d[i];
            def+=d[i];
 ss.push(i);
            ss.push(i);
 j=j-1;
            j=j-1;
 conc-=(p[i]-d[i]);
            conc-=(p[i]-d[i]);
 i=path[i-1][j][conc];
            i=path[i-1][j][conc];
 }
        }
 printf("Jury #%d\n",++test);
        printf("Jury #%d\n",++test);
 printf("Best jury has value %d for prosecution and value %d for defence:\n",prose,def);
        printf("Best jury has value %d for prosecution and value %d for defence:\n",prose,def);
 while(!ss.empty())
        while(!ss.empty())

 
         {
{
 printf(" %d",ss.top());
            printf(" %d",ss.top());
 ss.pop();
            ss.pop();
 }
        }
 printf("\n\n");
        printf("\n\n");
 }
    }
 return 0;
    return 0;
 }
}



posted on 2010-08-09 01:16 
wuxu 阅读(271) 
评论(0)  编辑 收藏 引用  所属分类: 
动态规划