hdu 1881 毕业bg (01背包变形)浙大计算机研究生复试上机考试-2008年

题目分析:题目搞不懂呀,尴尬,参考了,http://blog.csdn.net/kyle_once/article/details/6198468

才弄明白,一直把离校时间,理解错了....吧bg当做物品,欢乐度当做价值,持续时间当做体积,离校时间当做容量,放入顺序是有顺序的,要按离校时间升序排序,

定义dp[i][j],为吧前件bg安排到j时间内,所获得的最大欢乐度,

dp[i][j]=max(dp[i-1][j],dp[i-1][j-arr[i].l]+arr[i].h);  并且 arr[i].l<=j&&j<=arr[i].t



#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
int h,l,t;
}arr[35];
int dp[1000];//dp[i][j]把前i个bg安排到j时间内的最大欢乐度
int cmp(node x,node y)
{
	return x.t<y.t;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		if(n<0)
			break;
		for(int i=1;i<=n;i++)
			scanf("%d %d %d",&arr[i].h,&arr[i].l,&arr[i].t);
		sort(arr+1,arr+1+n,cmp);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
			for(int j=arr[n].t;j>=arr[i].l;j--)
				if(j>=arr[i].l&&j<=arr[i].t)
				    dp[j]=max(dp[j],dp[j-arr[i].l]+arr[i].h);
		int ans=0;
		for(int i=1;i<=arr[n].t;i++)
			if(dp[i]>ans)
				ans=dp[i];
		printf("%d\n",ans);
	}
	system("pause");
	return 0;
}
还可用不优化空间复杂度,用二维的做:

/****不压缩空间*****/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
int h,l,t;
}arr[35];
int dp[1000][1000];//dp[i][j]把前i个bg安排到j时间内的最大欢乐度
int cmp(node x,node y)
{
	return x.t<y.t;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		if(n<0)
			break;
		for(int i=1;i<=n;i++)
			scanf("%d %d %d",&arr[i].h,&arr[i].l,&arr[i].t);
		sort(arr+1,arr+1+n,cmp);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=arr[n].t;j++) //(int j=arr[n].t;j>=arr[i].l;j--)
				if(j>=arr[i].l&&j<=arr[i].t && dp[i-1][j-arr[i].l]+arr[i].h>dp[i-1][j])
					dp[i][j]=dp[i-1][j-arr[i].l]+arr[i].h;
				    //dp[i][j]=max(dp[i-1][j],dp[i-1][j-arr[i].l]+arr[i].h);
				else
					dp[i][j]=dp[i-1][j];

		int ans=0;
		for(int i=1;i<=arr[n].t;i++)
			if(dp[n][i]>ans)
				ans=dp[n][i];
		printf("%d\n",ans);
	}
	system("pause");
	return 0;
}


还可以用搜索做,不会搜索:

这个搜索模式和hdu1248 寒冰王座 一样的........不懂,参考别人的!!!!


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
int h,l,t;
}arr[35];
int ans,n;
int cmp(node x,node y)
{
	return x.t<y.t;
}
void dfs(int i,int h,int t)//i代表搜到第i个bg,h代表当前的欢乐度,t代表当前的截止时间
{
      if(ans<h)
		  ans=h;
	  if(i>n)
		  return ;
	  dfs(i+1,h,t);
	  if(t+arr[i].l<=arr[i].t)
		  dfs(i+1,h+arr[i].h,t+arr[i].l);
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n<0)
			break;
		for(int i=1;i<=n;i++)
			scanf("%d %d %d",&arr[i].h,&arr[i].l,&arr[i].t);
		sort(arr+1,arr+1+n,cmp);
		ans=0;
		dfs(1,0,0);
		printf("%d\n",ans);
	}
	system("pause");
	return 0;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值