【題目鏈接】
http://acm.hdu.edu.cn/showproblem.php?pid=5125
【解題報告】
求A的最長上升子序列,其中A中至多有M個元素可以被B中同位置元素替換。
考慮到數據範圍只有1e3,所以完全可以用O(n^2)的方法來求LIS,但是由於有了B數組的加入,所以我們需要考慮Dp的狀態要設置兩個,一個是從上一個狀態的a轉移過來,一個是從上一個狀態的b轉移過來。
所以轉移方程一共有2×2種情況,分類討論列寫轉移方程即可。並沒有太多難點,細心即可。
【參考代碼】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int dp[1000+100][2],m[1000+100][2],a[1100],b[1100];
int N,M;
void setdp( int i,int j,int Ki, int Kj )
{
dp[i][Ki]=dp[j][Kj]+1;
m[i][Ki]=m[j][Kj];
if( Ki==1 )m[i][Ki]+=1;
}
void solve()
{
memset( dp,0,sizeof dp );
memset( m,0,sizeof m);
// dp[1][0]=dp[1][1]=1;m[1][1]=1;
for( int i=1; i<=N; i++ )
for( int j=0; j<i; j++ )
{
if( a[i]>a[j] )if( dp[i][0]<dp[j][0]+1 || dp[j][0]+1==dp[i][0] && m[i][0]>m[j][0] )
setdp( i,j,0,0 );
if( a[i]>b[j] )if( dp[i][0]<dp[j][1]+1 || dp[i][0]==dp[j][1]+1 && m[i][0]>m[j][1] )
setdp( i,j,0,1 );
if( b[i]>a[j] )if( dp[i][1]<dp[j][0]+1 || dp[i][1]==dp[j][0]+1 && m[i][1]>m[j][0]+1 )
setdp(i,j,1,0);
if( b[i]>b[j] )if( dp[i][1]<dp[j][1]+1 || dp[i][1]==dp[j][1]+1 && m[i][1]>m[j][1]+1 )
setdp( i,j,1,1 );
}
}
int main()
{
int T; cin>>T;
while( T-- )
{
cin>>N>>M;
for( int i=1; i<=N; i++ ) cin>>a[i]>>b[i];
solve();
int ans=0;
for( int i=1; i<=N; i++ )
{
ans=( m[i][0]>M ) ? max( ans,dp[i][0]-m[i][0]+M ) : max( ans,dp[i][0] );
ans=( m[i][1]>M ) ? max( ans, dp[i][1]-m[i][1]+M ) : max( ans,dp[i][1] );
}
cout<<ans<<endl;
}
return 0;
}