P1970 花匠
状态定义是dp中非常重要的,可以直接影响到效率,如此题,第一种思路是:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct node {
int high, value;
bool operator < (const node &i) const{
return (this->value < i.value);
}
};
int main() {
int n;
scanf("%d", &n);
int fl[maxn];
for(int i = 1; i <= n; i++) scanf("%d", &fl[i]);
int f[maxn], g[maxn];
priority_queue<node> pf, pg;
f[1] = 1; g[1] = 1;
pf.push({fl[1], f[1]}); pg.push({fl[1], g[1]});
for(int i = 2; i <= n; i++) {
node x = pf.top();
node y = pg.top();
pf.pop(); pg.pop();
int cnt = 0;
while(x.high <= fl[i] && cnt < pf.size()) {
node e = pf.top(); pf.pop();
pf.push(x); x = e; cnt++;
}
cnt = 0;
while(y.high >= fl[i] && cnt < pg.size()) {
node e = pg.top(); pg.pop();
pg.push(y); y = e;cnt++;
}
f[i] = 1; g[i] = 1;
if(x.high > fl[i]) g[i] = x.value + 1;
if(y.high < fl[i]) f[i] = y.value + 1;
pf.push({fl[i], f[i]});
pg.push({fl[i], g[i]});
pf.push(x);
pg.push(y);
}
int ans = 0;
for(int i = 1; i <= n; i++) {
ans = max(ans, f[i]);
ans = max(ans, g[i]);
}
cout << ans;
}
定义f[i]为以i结束,加上优先队列优化,很麻烦,也容易被卡掉,复杂度不稳定,从O(nlogn)~O(n2)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int main() {
int n;
scanf("%d", &n);
int fl[maxn];
for(int i = 1; i <= n; i++) scanf("%d", &fl[i]);
int f[maxn], g[maxn];
f[1] = 1; g[1] = 1;
for(int i = 2; i <= n; i++) {
if(fl[i] > fl[i-1]) {
f[i] = max(f[i-1], g[i - 1]+1);
g[i] = g[i-1];
}
else if(fl[i] < fl[i-1]) {
f[i] = f[i-1];
g[i] = max(g[i-1], f[i-1] + 1);
}
else {
f[i] = f[i-1];
g[i] = g[i-1];
}
}
cout << max(f[n], g[n]);
}
定义f[i]为前i个数,不需要优化,效率高,复杂度降低到了O(n)!
算法真神奇。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步