Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

我被此题和VS2008玩疯了

Posted by elfin at 2008-09-11 16:43:27 on Problem 1015
调试啊,调试ING。

三重循环,看得眼睛都痛了。

/*
我的方法是DP,
定义一个数组:a[205][25][-450..450];
a[i][j][k]:前i个人中,选J个人,D(i) - P(i)差值为K时的最大和。

对于第i个人,显然我们可以不选他,即:a[i-1][j][k],也可以选他,即:a[i-1][j-1][k-D(i)+P(i)]+D(i)+P(i);
所以得动态转移方程:a[i][j][k]=max{a[i-1][j][j] ,a[i-1][j-1][k-D(i)+P(i)]+D(i)+P(i)};

这样我们就能保证其和最大。
考虑到a[i]只与前面的a[i-1]有关,于是可以用滚动数组来做,否则会MLE。。。

选的时候让k从0到400循环,碰到可以构成的a[n][m][k]即跳出,
此时D(i) - P(i)差最小。而此时的a[n][m][k]值即是其最大的和。

关于路径的记录,我们开个  bool used[205][25][-450..450]; 
把每次计算时的选择记录下来就行了。输出的时候就根据每次的选择倒过来走。

当然C语言中数组不允许下标为负数,所以我们只能定义成a[205][25][850];这样,然后每次给他加上400再用即可。
*/
	

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

const int  MAX=1023;
const int  UNUSED=1023;

int d[205],p[205];

static bool used[205][25][805];




void output(int i,int j,int tk) 
{
	if(i==j)
	{
		for(int w=1;w<=i;w++)
		{
			cout<<w<<' ';
		}
	}
	else
	{
		if(used[i-1][j][tk])
		{
			output(i-1,j,tk);
		}
		else if(used[i-1][j-1][tk-d[i]+p[i]])
		{
			output(i-1,j-1,tk-d[i]+p[i]);
			cout<<i<<' ';
		}
	}
	return;
}



int main()
{
	int m,n;


	cin>>m>>n;





	for(int t=1;t<=m;t++)
	{
		cin>>p[t]>>d[t];
	}






	int dptable[2][25][805];//保存动态规划状态的结果,循环保存 [i][][] 和 [i+1][][] 的状态值
	memset(dptable,UNUSED,2*25*805);//初始化为未使用
	memset(used,false,205*25*805);
	










	for(int count=1;/*为i计数,直到m*/count<=n;
		count++)
	{
		int i=count%2;
		int next=i?0:1;
		//这里填入初始化数组

		int tpk=0;
		int sum=0;

		for(int x=1;x<=i;x++)
		{
			tpk+=p[i];
		}
		sum=tpk;
		for(int x=1;x<=i;x++)
		{
			tpk-=d[i];
			sum+=d[i];
		}

		dptable[i][i][tpk]=sum;//以上为i选i填表
		
		dptable[i][0][0]=0;//以上为i选1填表


		for(int j=1;j<=i;
			j++)
		{

			for(int k=0;k<=20*j;
				k++)
			{
				int tpk=	k	+400;

				if(dptable[i][j][tpk]	<=	dptable[i][j-1][tpk-d[i]+p[i]]+d[i]+p[i])
				{
					dptable[next][j][tpk]=dptable[i][j][tpk];//状态转化函数
					
					used[count][j][tpk]=true;
				}
				else
				{
					dptable[next][j][tpk]=dptable[i][j-1][tpk-d[i]+p[i]]+d[i]+p[i];
					
					used[count][j-1][tpk-d[i]]=true;
				}
				
				int tpk2=	-k	+400;

				if(dptable[i][j][tpk2]	<=	dptable[i][j-1][tpk2-d[i]+p[i]]+d[i]+p[i])
				{
					dptable[next][j][tpk2]=dptable[i][j][tpk2];//状态转化函数
					
					used[count][j][tpk2]=true;
				}
				else
				{
					dptable[next][j][tpk]=dptable[i][j-1][tpk-d[i]+p[i]]+d[i]+p[i];
					
					used[count][j-1][tpk-d[i]]=true;
				}






				if(count==n	&&	j==m	&& (dptable[next][j][tpk]<1000||dptable[next][j][tpk2]<1000))//完成算法
				{
					if(dptable[next][j][tpk]<dptable[next][j][tpk2])
					{
						output(next,j,tpk);

					}
					else
					{
						
						output(next,j,tpk2);

					}


				}

			}


		
		}
	}



	return 0;






	



}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator