您的位置:首页 > 其它

POJ 1015 Jury Compromise 双塔DP

2013-03-30 19:46 447 查看
题意:审判囚犯了,要在n选择m个人组成陪审团,每个人对那个囚犯有一个好感值,厌恶值。为了保证审判,陪审团要保证公正,所以在保证所有人的好感值和与厌恶值和的差值最小,然后确保好感值和厌恶值和的总值最大。

做法:记录的状态是当前好感值和厌恶值的差值,当前好感值的和与厌恶值的和,DFS求出选择方案。o(︶︿︶)o 唉,最后取答案的之后,竟然把n写成了i,wa多次

#include<cstdio>
#include<cstring>
const int LMT=202;
const int offset=400;
int dp[2][25][805][2];
bool vis[LMT][25][805];
struct jury
{
	int d,p;
}ju[LMT];
inline int max(int a,int b)
{
	return a>b?a:b;
}
inline int min(int a,int b)
{
	return a<b?a:b;
}
void init(void)
{
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dp[0][0][offset][0]=dp[0][0][offset][1]=0;
	ju[0].d=ju[0].p=0;
}
inline int abs(int x)
{
	return x>0?x:-x;
}
void dfs(int i,int j,int k)
{
	if(i<=0)return;
	if(vis[i][j][k])
	{
		dfs(i-1,j-1,k-ju[i].d+ju[i].p);
		printf(" %d",i);
	}
	else dfs(i-1,j,k);
}
int main(void )
{
	int i,j,di,n,m,ans,ansm,x,dm,pm,use,I=1;
	while(~scanf("%d%d",&n,&m)&&(m||n))
	{
		init();
		ans=100000000;
		ansm=0;dm=pm=0;
		for(i=1;i<=n;i++)
			scanf("%d%d",&ju[i].p,&ju[i].d);
		for(i=1;i<=n;i++)
		{
			dp[i&1][0][offset][1]=dp[i&1][0][offset][0]=0;
		    for(di=offset<<1;di>=0;di--)
		    {
		        x=di-ju[i].d+ju[i].p;
		      for(j=m;j>0;j--)
		      {
		           if(x>=0&&x<=offset<<1&&dp[(i-1)&1][j-1][x][0]!=-1)
                   {
		               if(dp[(i-1)&1][j-1][x][0]+ju[i].d+ju[i].p
                         +dp[(i-1)&1][j-1][x][1]
                        >dp[i&1][j][di][0]+dp[i&1][j][di][1])
                      {
                           dp[i&1][j][di][0]=dp[(i-1)&1][j-1][x][0]+ju[i].d;
                           dp[i&1][j][di][1]=dp[(i-1)&1][j-1][x][1]+ju[i].p;
                            vis[i][j][di]=1;
                      }
                    }
                     if(dp[(i-1)&1][j][di][0]+dp[(i-1)&1][j][di][1]
                         >dp[i&1][j][di][0]+dp[i&1][j][di][1])
                     {
                        vis[i][j][di]=0;
                        dp[i&1][j][di][0]=dp[(i-1)&1][j][di][0];
                        dp[i&1][j][di][1]=dp[(i-1)&1][j][di][1];
                     }
              }
		    }
		}
		for(di=0;di<=offset<<1;di++)
           if(dp[n&1][m][di][0]!=-1&&ans>abs(di-offset))
        {
            ans=abs(di-offset);
            use=di-offset;
            ansm=dp[n&1][m][di][0]+dp[n&1][m][di][1];
        }
          else if(ans==abs(di-offset)&&ansm<dp[n&1][m][di][0]+dp[n&1][m][di][1])
        {
            ansm=dp[n&1][m][di][0]+dp[n&1][m][di][1];
            use=di-offset;
        }
            printf("Jury #%d\n",I++);
            printf("Best jury has value %d for prosecution and value %d for defence:\n",
                   dp[n&1][m][use+offset][1],dp[n&1][m][use+offset][0]);
            dfs(n,m,use+offset);
            printf("\n");
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: