码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2392 Space Elevator DP

时间:2016-05-08 10:28:26      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

该题与poj 1742的思路基本一致:http://www.cnblogs.com/sevenun/p/5442279.html(多重背包)

 

题意:给你n个电梯,第i个电梯高h[i],数量有c[i]个,但是每个电梯所在高度不能超过a[i].

   求问,怎么样的建造方案能够使电梯能够达到最大高度

 

思路:首先,必然要使电梯按a[i]进行排序,a[i]最小的电梯先建造。例如,电梯1,只能在高度20以下建造,而电梯2能在高度50以下建造,我当然先建造电梯1,否则如果先建造电梯2,就会导致我建造的高度早早超过了20,这样就无法充分利用了电梯1。

   动态规划,想到转移方程为d[i][j],前i个电梯建造到高度j时,第i个电梯所剩余多少个。
   默认d[i][j]为-1,代表前i个电梯无法达到高度j。 

   对于d[i][j],如果前i-1个电梯的建造已能够达到高度j,那么到高度j自然就不需要第i个电梯,所以就剩余c[i]个电梯

   如果前i-1个电梯的建造不能达到高度j,那么我自然就要利用第i个电梯看看是否能够达到高度j,所以d[i][j] = d[i][j-h[i]]-1。

 

滚动数组:由于n最大为400,且a[i]最大为40000,那么由上面的定义,那么数组肯定就要达到400*40000了,感觉内存不够了

     所以观察方程可知,d[i][j]的计算只会涉及到前一行和当前行,所以可以利用滚动数组,从而减少内存的使用。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int K = 404;
const int H = 40005;
int n,d[2][H];
struct node
{
	int a,c,h;
}w[K];
int cmp(node n1, node n2)
{
	return n1.a < n2.a;
}
void solve()
{
	int f = 1;
	memset(d, -1, sizeof(d));
	sort(w,w+n,cmp);
	
	for(int j = 0; j*w[0].h <= w[0].a; j++)
		d[0][j*w[0].h] = w[0].c - j;
	
	for(int i = 1; i < n; i++)
	{
		d[f][0] = w[i].c;
		for(int j = 1; j <= min(w[i].a, H); j++)
		{
			if(d[!f][j] >= 0) d[f][j] = w[i].c;
			else if(j >= w[i].h) d[f][j] = d[f][j-w[i].h]-1;
			else d[f][j] = -1;
			d[!f][j] = -1;
		}
		d[!f][0] = -1;
		f = !f;
	}
	int ans = 0;
	for(int i = w[n-1].a; i >= 0; i--)
	{
		ans = i;
		if(d[!f][i]>= 0) break;
	}
	printf("%d\n", ans);
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	while(~scanf("%d", &n))
	{
		for(int i = 0; i < n; i++)
			scanf("%d %d %d", &w[i].h, &w[i].a, &w[i].c);
		solve();
	}
	return 0;
}

  

poj 2392 Space Elevator DP

标签:

原文地址:http://www.cnblogs.com/sevenun/p/5469866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!