hdu3033

/*
分析:
    代码有点儿乱,有空了写个清楚的。

    思路:在代码里。

    注意,下面说的继承都是间接地,是包含了自己的继承,而不是只是单一的把dp[i-1]的当前值直接拿过来,

因为如果这样的话,就没有i的元素在里面了



    困扰菜菜三天的题了,终于搞定了,弄的我写完了都不敢
提交了 - - I 。


                                              2012-07-13
*/










#include"stdio.h"
#include"string.h"
#include"stdlib.h"


struct A
{
	int num;
	struct B
	{
		int v;
		int val;
	}E[111];
}bra[11];


int M(int a,int b)
{
	return a>b?a:b;
}
int cmp(const struct B *a,const struct B *b)
{
	return a->v-b->v;
}


int dp[11][10011];
int main()
{
	int n,V,k;
	int i,l,j;
	int a,b,c;
	int flag;
	int temp;
	int ans;


	while(scanf("%d%d%d",&n,&V,&k)!=-1)
	{
		///读入以及编组
		for(i=1;i<=k;i++)	bra[i].num=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			bra[a].E[bra[a].num].v=b;
			bra[a].E[bra[a].num].val=c;
			bra[a].num++;
		}
		//这里有个排序,把每个序列的成员,按照price,亦即这儿的v来排序,从小到大
		for(i=1;i<=k;i++)	qsort(bra[i].E,bra[i].num,sizeof(bra[i].E[0]),cmp);


		///特殊情况
		flag=0;
		for(i=1;i<=k;i++)	if(bra[i].num==0)	{flag=1;break;}
		if(flag)	{printf("Impossible\n");continue;}


		///DP
		memset(dp,0,sizeof(dp));
		flag=0;
		//先把第一系列的0-1背包弄下
		for(i=0;i<bra[1].num;i++)
		for(l=V;l>=bra[1].E[i].v;l--)	dp[1][l]=M(dp[1][l],dp[1][l-bra[1].E[i].v]+bra[1].E[i].val);
		//然后从第二系列开始
		for(i=2;i<=k;i++)
		{
			//先用i系列的第一件物品,去继承i-1系列的情况,因为qsort过了,所以i系列第一个一定是i系列中,能继承i-1系列格子做多的,同时也保证了在dp[i][l]!=0的地方,一定有上一个系列继承来的值,也就保证每个系列至少取一个
			for(l=V;l>=0;l--)
			{
				temp=l-bra[i].E[0].v;
				if(dp[i-1][temp]==0)	break;
				dp[i][l]=dp[i-1][temp]+bra[i].E[0].val;
			}
			for(j=1;j<bra[i].num;j++)
			{
				//i系列内斗
				for(l=V;l>=0;l--)
				{
					temp=l-bra[i].E[j].v;
					if(dp[i][temp]==0)	break;               //限定1
					dp[i][l]=M(dp[i][l],dp[i][temp]+bra[i].E[j].val);
				}
				//i系列继承i-1
				for(l=V;l>=0;l--)
				{
					temp=l-bra[i].E[j].v;
					if(dp[i-1][temp]==0)	break;           //限定2。这两个限定保证了不会从dp=0的地方弄来值
					dp[i][l]=M(dp[i][l],dp[i-1][temp]+bra[i].E[j].val);
				}
			}
			if(dp[i][V]==0)	{flag=1;break;}
		}


		if(flag)	printf("Impossible\n");
		else		printf("%d\n",dp[k][V]);
	}
	return 0;
}


你可能感兴趣的:(hdu3033)