第八章:高效算法设计
UVA11093 Just Finish it up
最直接的办法:选取正收益的点开始,O(n) judge。但有个必须注意到的性质,即如果一个起点不合法,那么刚才扫过的所有点不不合法。于是时间复杂度就降下来了。
明明就很简单呀!为什么想不到呢。先确定一般暴力解、正解时间复杂度,然后再逐步想如何优化。想算法,想不到就回来找性质。
UVA12174 Shuffle
滑动窗口。思考:下一次Shuffle的起点有何性质?
- 除开头,之后的均是完整的s序列
- 开头没有重复数字
- 开头的长度确定,整体状态唯一
显然,由1、3,中间只要有一段不合法,对应的Shuffle起点不成立
于是想到,用滑动窗口记录每一次滑动时合不合法,再映射回“开头”的end用于记录(同时想到:最多只有s个答案)
那么剪掉不合法的就是正确答案。
那么怎么记录当前滑动窗口合不合法?
思考:什么时候不合法
答:有重复数字的时候
于是,仅需要记录有多少重复的数字
思考:怎么记录
思考:滑一次有什么影响?
答:有数进有数出,也就是可能出现新重复,也可能减去原有重复。
思考:我需要记录什么->我关心谁重复吗?
答:不关心
于是想到,直接用一个int cnt记录即可。
int cnt = 0;
for (int i = 1; i <= n+s; i++) {if (i > s) {--wnd[x[i-s]];if (wnd[x[i-s]] == 1) --cnt;}++wnd[x[i]];if (wnd[x[i]] > 1 && x[i]) ++cnt;if (cnt) ilg[i%s] = 1;
}`
这题必须好好反思。可以看出自己的思维混乱,没想清楚就开始打代码。man!你自己看看你一开始都打的啥呀!!!