现在的位置: 首页 > 综合 > 正文

ZOJ1303

2019年08月20日 ⁄ 综合 ⁄ 共 1356字 ⁄ 字号 评论关闭

特别坑的题目,反正我被坑死了,终于AC了,

题目想了下,写错了,然后看下别人的代码发现思路错了(菜啊),然后自己再去写,

随便怎么dp都行,我是外循环从1-》m dp[0||1][j]表示差为j时的最大sum,再用个path记路径就醒了

后来wa的原因想了好久,竟然是滚动数组没层都要memset,忘了,汗!!

#include<cstdio>
#include<cstring>
#include<algorithm>
#define pi 400
using namespace std;
int d[220],s[220];
int dp[2][810];
int path[21][810],cnt;
int n,m;
void DP()
{
	int p=1,q=0;
	memset(dp,-1,sizeof(dp));
	memset(path,0,sizeof(path));
	for(int i=1;i<=n;i++)
	{
		if(s[i]>dp[0][pi+d[i]])
		{
			dp[0][pi+d[i]]=s[i];
			path[1][pi+d[i]]=i;
		}
	}
	for(int i=1;i<m;i++,p^=1,q^=1)
	{
		memset(dp[p],-1,sizeof(dp[p]));
	for(int k=0;k<=800;k++)
	{
		if(path[i][k])
		{
			for(int j=1;j<=n;j++)
			{
				if(k+d[j]<0||k+d[j]>800)
					continue;
				if(dp[p][k+d[j]]<dp[q][k]+s[j])
				{
					int k1,k2;
					for(k1=i,k2=k;k1>0;k1--)
					{
						if(path[k1][k2]==j)break;
						k2-=d[path[k1][k2]];
					}
					if(k1==0)
					{
						dp[p][k+d[j]]=dp[q][k]+s[j];
						path[i+1][k+d[j]]=j;
					}
				}	
			}
		}
	}
	}
	p^=1;
	printf("Jury #%d\n",++cnt);
	int maxn=-1,in=-1;
	for(int i=0;i<=400;i++)
	if(dp[p][pi+i]!=-1||dp[p][pi-i]!=-1)
	{
		if(dp[p][pi+i]>dp[p][pi-i])
			maxn=dp[p][pi+i],in=i;
		else
			maxn=dp[p][pi-i],in=-i;
		break;
	}
	printf("Best jury has value %d for prosecution and value %d for defence:\n",(maxn+in)/2,(maxn-in)/2);
	int num[210];
	int tot=0;
	int ll=pi+in;
	while(m)
	{
		num[++tot]=path[m][ll];
		ll-=d[path[m][ll]];
		m--;
	}
	sort(num+1,num+1+tot);
	for(int i=1;i<=tot;i++)
		printf(" %d",num[i]);
	puts("\n");
	return;
}
int main()
{
	while(scanf("%d%d",&n,&m),n||m)
	{	
		for(int i=1;i<=n;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			d[i]=a-b;
			s[i]=a+b;
		}
		DP();
	}
	return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.