HDU 1950 Bridging signals 解题报告
解题思路:这题目看起来烦,实际上就是让你找最长上升子序列,我一开始还被唬住了。。。有两种找的方法,一种是dp算法,一种是LIS算法。
1.dp方法。一个不幸的消息,tle了,这道题上dp算法确实慢点。
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int n,p;
int a[40005];
int dp[40005];
int main()
{
cin >> n;
while (n--)
{
int ans=-1;
memset(dp, 0, sizeof(dp));
cin >> p;
for(int i = 1; i <= p; i++)
{
cin >> a[i];
dp[i] = 1;
}
for (int i = 2; i <= p; i++)
{
for (int j = 1; j <= i; j++)
{
if (a[i] > a[j])
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
ans = max(ans, dp[i]);
}
cout << ans<< endl;
}
}
2.LIS算法。发个链接吧:https://blog.csdn.net/Fire_to_cheat_/article/details/78297534。我懒的讲思维了。如果还看不懂就举例子想,多想想总会懂的。
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int n,p;
int a[40005];
int tem[40005];
int main()
{
cin >> n;
while (n--)
{
memset(tem, 0, sizeof(tem));
cin >> p;
for(int i = 1; i <= p; i++)
{
cin >> a[i];
}
tem[1] = a[1];
int len = 1;//子序列长度最少是1
for (int i = 2; i <= p; i++)
{
if (a[i] > tem[len])
{
len++;
tem[len] = a[i];
}
else
{
int pos = lower_bound(tem + 1, tem + len + 1, a[i]) - tem;//因为lower_bound()是二分查找,所以很快
tem[pos] = a[i];
}
}
cout << len<< endl;
}
}