洛谷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;
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步