贪心解法:
[解题思路]
首先将线段端点调整为左端点小于(或等于)右端点;
第二,根据右端点将线段从小到大排序;
第三,扫描一遍,每次遇到的第一个与当前的max不相交的即为最优选择。
[代码实现]
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=101;
struct node
{
int begin,end;
}a[N];
bool cmp(node a,node b)
{
return a.end<b.end;
}
int main()
{
int n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&a[i].begin,&a[i].end);
if(a[i].begin>=a[i].end)
{
swap(a[i].begin,a[i].end);
}
}
sort(a+1,a+n+1,cmp);
int max=-1000;
for(int i=1;i<=n;i++)
{
if(a[i].begin>=max)
{
ans++;
max=a[i].end;
}
}
printf("%d\n",ans);
return 0;
}
序列型动态规划(DP):
[解题思路]
前两步同上
第三步,dp[i] = max(dp[i], (dp[j]+1))。
第四,选择dp数组中最大值即为结果。
[代码实现]
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=101;
int dp[N];
struct node
{
int begin,end;
}a[N];
bool cmp(node a,node b)
{
return a.end<b.end;
}
int main()
{
int n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
dp[i]=1;
scanf("%d %d",&a[i].begin,&a[i].end);
if(a[i].begin>=a[i].end)
{
swap(a[i].begin,a[i].end);
}
}
sort(a+1,a+n+1,cmp);
for(int i=2;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
if(a[i].begin>=a[j].end)
{
dp[i]=max(dp[i],(dp[j]+1));
if(ans<dp[i]) ans=dp[i];
}
}
}
printf("%d\n",ans);
return 0;
}