1.拦截导弹 (NOIP1999提高组)
http://codevs.cn/problem/1044/
方程:
最长不上升子序列f[i] = max(f[i], f[j]+1) (h[j] >= h[i])
最长上升子序列g[i] = max(g[i], g[j]+1) (h[j] < h[i])
代码:
#include<bits/stdc++.h>
#define MAX_N 21
#define MAX_HEIGHT 30001
using namespace std;
int h[MAX_N];
int f[MAX_N], g[MAX_N];
int main()
{
int n = 0;
while (scanf("%d", &h[n]) != EOF)
n++;
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g));
for (int i = 0; i < n; i++)
{
f[i] = 1;
g[i] = 1;
for (int j = 0; j < i; j++)
{
if (h[j] >= h[i]) f[i] = max(f[i], f[j]+1);
if (h[j] < h[i]) g[i] = max(g[i], g[j]+1);
}
}
int res1 = 0, res2 = 0;
for (int i = 0; i < n; i++)
{
res1 = max(res1, f[i]);
res2 = max(res2, g[i]);
}
cout << res1 << endl << res2;
return 0;
}
2.线段覆盖2(CodeVS3027)
http://codevs.cn/problem/3027/
算法:将线段按右端点升序排序后转化为最长不下降子序列模型
代码:
#include<bits/stdc++.h>
#define MAX_N 1001
using namespace std;
int f[MAX_N];
struct node
{
int a, b, c;
}line[MAX_N];
bool cmp(node xi, node xj)
{
return (xi.b < xj.b);
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> line[i].a >> line[i].b >> line[i].c;
sort(line, line+n, cmp);
memset(f, 0, sizeof(f));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
if (line[j].b <= line[i].a) f[i] = max(f[i], f[j]);
f[i] += line[i].c;
}
int res = 0;
for (int i = 0; i < n; i++)
res = max(res, f[i]);
cout << res;
return 0;
}