惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
腾讯CDC
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
量子位
博客园 - 聂微东
Jina AI
Jina AI
小众软件
小众软件
The Cloudflare Blog
有赞技术团队
有赞技术团队
V
V2EX
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
B
Blog
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog
宝玉的分享
宝玉的分享
C
Check Point Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
IT之家
IT之家
N
Netflix TechBlog - Medium
I
InfoQ
J
Java Code Geeks
S
SegmentFault 最新的问题
V
Visual Studio Blog
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
D
DataBreaches.Net
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog RSS Feed
S
Schneier on Security
Webroot Blog
Webroot Blog
P
Proofpoint News Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
Project Zero
Project Zero
Scott Helme
Scott Helme
C
CERT Recently Published Vulnerability Notes
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security

博客园 - zealsoft

洛谷 P1816 忠诚题解 洛谷 P2384 最短路题解 洛谷 P2725 邮票题解 洛谷 P2722 总分题解 洛谷 P1219 八皇后题解 洛谷 P2921 在农场万圣节Trick or Treat on the Farm题解 洛谷 P1162 填涂颜色题解 洛谷 P1330 封锁阳光大学题解 洛谷 P1032 字串变换题解 洛谷 P1443 马的遍历题解 洛谷 P1020导弹拦截题解 洛谷 P1141 01迷宫题解 VisualSVNServer无法卸载也无法安装,报告不是有效的MOF文件(0x8004401e)错误 视频捕捉的格式问题 一个VxWorks源代码网站 找个轻量级的Log库还挺难 TAU G2中的BitString和OctetString W32.Downadup.autorun病毒的清除 如何用Visual Studio 2005编译Wireshark的插件
洛谷 P1280 尼克的任务题解
zealsoft · 2019-08-10 · via 博客园 - zealsoft

题目链接:https://www.luogu.org/problem/P1280

题目描述

尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。

尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。

写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。

输入格式

输入数据第一行含两个用空格隔开的整数N和K(1≤N≤10000,1≤K≤10000),N表示尼克的工作时间,单位为分钟,K表示任务总数。

接下来共有K行,每一行有两个用空格隔开的整数P和T,表示该任务从第P分钟开始,持续时间为T分钟,其中1≤P≤N,1≤P+T-1≤N。

输出格式

输出文件仅一行,包含一个整数,表示尼克可能获得的最大空暇时间。

输入输出样例

输入 #1

15 6
1 2
1 6
4 11
8 5
8 1
11 5

题解

这题一般的解法都是DP。其实是可以用DFS暴力过的。

先介绍一个TLE的代码。这个代码中我们没有对任务进行时间排序,而是将任务信息保存在vis数组中。vis[i][0]保存着开始时间为i的时候的任务数,而vis[i][1]……vis[i][n]保存着开始时间为i的各任务的持续时间。

 1 #include <iostream>
 2 #include <math.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <string.h>
 6 
 7 using namespace std;
 8 
 9 const int MAXN = 1e4 + 5;
10 int n, t, start[MAXN], keep[MAXN], vis[MAXN][1005];
11 
12 int dfs(int st)
13 {
14     if(st >= t)
15     {
16         return 0;
17     }
18     if(vis[st][0] == 0)
19     {
20         st++;
21         return dfs(st);
22     }    
23     else
24     {    
25         int mint = 0x3f3f3f;
26         for(int i = 1; i <= vis[st][0]; i++)
27         {
28             int w = dfs(st + vis[st][i]);
29             if(mint > w + vis[st][i])
30             {
31                 mint = w + vis[st][i];
32             }
33         }
34         return mint;
35     }
36 }
37 
38 int main()
39 {
40     cin >> t >> n;
41     for(int i = 1; i <= n; i++)
42     {
43         cin >> start[i] >> keep[i];
44         vis[start[i]][0]++;
45         vis[start[i]][vis[start[i]][0]] = keep[i];
46     }
47     cout << t - dfs(1) << endl;
48     return 0;
49 }

要避免TLE,可以将每个子节点深搜的结果保存在data中,如果已经搜素过该子节点,就不再搜素了,这样就可以AC了。

 1 #include <iostream>
 2 #include <math.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <string.h>
 6 
 7 using namespace std;
 8 
 9 const int MAXN = 1e4 + 5;
10 int n, t, start, keep, vis[MAXN][1005];
11 int data[MAXN];
12 
13 int dfs(int st)
14 {
15     if(st > t)
16     {
17         return 0;
18     }
19     if(data[st])
20     {
21         return data[st];
22     }
23     if(vis[st][0] == 0)
24     {
25         st++;
26         return dfs(st);
27     }    
28     else
29     {    
30         int mint = 0x3f3f3f;
31         for(int i = 1; i <= vis[st][0]; i++)
32         {
33             int w = dfs(st + vis[st][i]);
34             if(mint > w + vis[st][i])
35             {
36                 mint = w + vis[st][i];
37             }
38         }
39         data[st] = mint;
40         return mint;
41     }
42 }
43 
44 int main()
45 {
46     cin >> t >> n;
47     for(int i = 1; i <= n; i++)
48     {
49         cin >> start >> keep;
50         vis[start][0]++;
51         vis[start][vis[start][0]] = keep;
52     }
53     cout << t - dfs(1) << endl;
54     return 0;
55 }