洛谷P1280 && caioj 1085 动态规划入门(非常规DP9:尼克的任务)

这道题我一直按照往常的思路想
f[i]为前i个任务的最大空暇时间
然后想不出来怎么做……
后来看了题解
发现这里设的状态是时间,不是任务
自己思维还是太局限了,题做得太少。

很多网上题解都反着做,那么麻烦干嘛

设f[i]为前i时间内的最大空暇时间。
这里是更新后来的状态,和以前不一样。
如果i为某个任务的开始时间,则
f[i+t-1] = max(f[i+t-1], f[i])
也就是继承过去,取max
如果不是的话
f[i] = max(f[i], f[i-1] + 1)
加上获得的空暇时间
最后输出f[time],time为总时间

#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;

const int MAXN = 11234;
int f[MAXN], time, n;
struct node
{
	int l, r;
	bool operator < (const node& rhs) const
	{
		return l < rhs.l || (l == rhs.l && r < rhs.r); 
	}
}a[MAXN];

int main()
{
	scanf("%d%d", &time, &n);
	REP(i, 1, n + 1) scanf("%d%d", &a[i].l, &a[i].r);
	sort(a + 1, a + n + 1);
	
	memset(f, -63, sizeof(f));
	f[0] = 0;
	int p = 1;
	REP(i, 1, time + 1)
	{
		if(a[p].l == i)
		{
			while(a[p].l == i)
				f[i + a[p].r - 1] = max(f[i + a[p].r - 1], f[i-1]), p++;
		}
		else f[i] = max(f[i], f[i-1] + 1);
	}
	printf("%d\n", f[time]);
	
	return 0;
}

后来做到洛谷P1280,竟然做不出来了,看来对题解还是没有深刻的理解
(1)初始化问题。本来以为全部都是0无所谓的,然后就WA。
因为求最大,所以初始化为最小,同时f[0] = 0
(2)这里推时间是从f[i-1]推,不是f[i]

 

 

然后我发现把这个f数组输出来乱七八糟的。
但是答案是对的
有点迷(因为下标是时间??)

最后,这11天过来我的代码风格还是有少许改变的

#include<cstdio>
#include<algorithm>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;

const int MAXN = 112345;
int f[MAXN], n, k;
struct node 
{ 
	int l, r;
	void read() { scanf("%d%d", &l, &r); r = l + r - 1; }
	bool operator < (const node& rhs) const
	{
		return l < rhs.l || (l == rhs.l && r < rhs.r);
	}
}a[MAXN];

int main()
{
	scanf("%d%d", &n, &k);
	REP(i, 0, k) a[i].read();
	sort(a, a + k);
	
	memset(f, -63, sizeof(f));
	f[0] = 0;
	int p = 0;
	_for(i, 1, n)
	{
		if(a[p].l == i)
		{
			while(a[p].l == i) 
				f[a[p].r] = max(f[a[p].r], f[i-1]), p++;
		}
		else f[i] = max(f[i], f[i-1] + 1);
	}
	printf("%d\n", f[n]);

	return 0;
}

 

posted @ 2018-08-26 15:38  Sugewud  阅读(141)  评论(0编辑  收藏  举报