给定一个数组
,让你找出一个最长上升子序列的长度,例如[1,4,6,2,3,5]
答案为4:[1,2,3,5]。
我们用DP[i]表示以下标为i的元素结尾的子序列的最长上升子序列长度
代码如下:
ll p[10010];
ll dp[10010];
int main()
{
ll n, ans = 0;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> p[i];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j < i; j++)
{
if (p[i] > p[j])
dp[i] = max(dp[i], dp[j] + 1);
}
ans = max(dp[i] + 1, ans);
}
cout << ans << endl;
return 0;
}
下面是今天下午没写出来的一个题,LIS其实很早就看到过了,也是很简单的DP,一直没写,说来惭愧。
这个我写了好久,中间都快自己写出LIS了,可惜一直差一点。看完LIS就很简单了。
我们可以发现,如果可以当前在魔法方格上并且2*W1<W2,那么肯定选择一步走到右上角。而且如果只用方式一移动,那么代价是确定的,2*n*W1
,因此其实就是找,最多可以经过几个魔法方格。
那么就是找最长上升子点(坐标?)了。
代码:
struct node
{
ll x, y;
bool operator<(const node &temp) const
{
if (x == temp.x)
return y < temp.y;
return x < temp.x;
}
} p[2010];
ll dp[2010];
int main()
{
ll n, k, w1, w2, ans = 0;
cin >> n >> k >> w1 >> w2;
for (int i = 1; i <= k; i++)
cin >> p[i].x >> p[i].y;
if (w1 * 2 <= w2)
return cout << 2 * n * w1 << endl, 0;
sort(p + 1, p + 1 + k);
for (int i = 1; i <= k; i++)
{
for (int j = 1; j < i; j++)
{
if (p[i].x > p[j].x && p[i].y > p[j].y)
dp[i] = max(dp[i], dp[j] + 1);
}
ans = max(ans, dp[i] + 1);
}
cout << 2 * n * w1 - ans * (2 * w1 - w2) << endl;
return 0;
}