洛谷P1280 尼克的任务

题目

该题目标签是DP,但是其实数据范围可以用记忆化搜索来解决,并且代码实现起来会简单一些,用二分查找来优化。

#include <bits/stdc++.h>
using namespace std;
int n, k, minn = 2147483647, dp[101000]; 
multimap <int, int> m;
struct dat {	
	int l, r, t;
}data[100100];	
bool cmp(dat a, dat b)
{				
	if (a.l == b.l)
		return a.r < b.r; 
	return a.l < b.l;
} 
/*		
void dfs(int pos, int now)
{				
//	data[pos].vis = 1;
	int l = data[pos].l, r = data[pos].r, t = data[pos].t;
	for (int i = pos + 1; i <= k + 1; i++)
	{			
		int l2 = data[i].l;
		if (i == 2 && l == 0)
			break;
//		if (data[i].vis) continue;
		if (i == k + 1)
			minn = min(minn, now + t), printf("%d ", minn);
		if (l2 > r)
		{
			if (r == 0)
				dfs(i, now);
			dfs(i, now + t);
//			data[i].vis = 0;
		}
	}
}*/
int dfs(int now)//now 代表时间 
{
	if (now > n) return 0;
	if (dp[now])
		return dp[now];
	int mintemp = 2147483647;//mintemp是当前的最小值。
	for (auto i = m.lower_bound(now); i != m.upper_bound(now); ++i )//找==now的数据
		mintemp = min(mintemp, dfs (i->second) + i->second - i->first);
	if (mintemp == 2147483647)//如果没有等于now的数据就找now+1
		mintemp = dfs(now + 1);
	return dp[now] = mintemp;
}
int main()
{
	
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= k; i++)
		scanf("%d%d", &data[i].l, &data[i].t), data[i].r = data[i].l + data[i].t, m.insert( {data[i].l, data[i].r} ) ;	
	sort(data + 1, data + 1 + k, cmp);
	minn = dfs(1);
	printf("%d", n - minn);
	return 0;
}
原文地址:https://www.cnblogs.com/liuwenyao/p/10956386.html