The town of W has N people. Each person takes two magic balls A and B every day. Each ball has the volume aiai and bibi. People often stand together. The wizard will find the longest increasing subsequence in the ball A. The wizard has M energy. Each point of energy can change the two balls’ volume.(swap(ai,bi)swap(ai,bi)).The wizard wants to know how to make the longest increasing subsequence and the energy is not negative in last. In order to simplify the problem, you only need to output how long the longest increasing subsequence is.
Input
The first line contains a single integer T(1≤T≤20)T(1≤T≤20)(the data for N>100N>100 less than 6 cases), indicating the number of test cases.
Each test case begins with two integer N(1≤N≤1000)N(1≤N≤1000) and M(0≤M≤1000)M(0≤M≤1000),indicating the number of people and the number of the wizard’s energy. Next N lines contains two integer aiai and bi(1≤ai,bi≤109)bi(1≤ai,bi≤109),indicating the balls’ volume.
Output
For each case, output an integer means how long the longest increasing subsequence is.
Sample Input
2
5 3
5 1
4 2
3 1
2 4
3 1
5 4
5 1
4 2
3 1
2 4
3 1
Sample Output
4
4
思路:这个题是最长递增序列问题,其中不同的一点是,A和B可以交换(有限制),可以用动态规划来实现。对于每个人来说,可以按A球或B球来计算分。分别用alen[]和blen[]数组来存。第i个人的球如果是用A球算,前i个人的总volume用alen[i]表示,ac[i]表示其进行的swap次数,第i个人的球如果按B球算,前i个人的volume用blen[i]表示,bc[i]表示其进行的swap次数。
转移方程:
(1)Aj+A
(2)Bj+A
(3)Aj+B
(4)Bj+B
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define N 1005
int a[N],b[N],ac[N],bc[N],alen[N],blen[N];
//ac表swap次数,alen表volume。
int main(){
int t,n,m;
cin>>t;
while(t--){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
for(int i=0;i<n;i++){
ac[i]=0;
bc[i]=0;
}
for(int i=0;i<n;i++){
alen[i]=1;
for(int j=0;j<i;j++){
if(a[j]<a[i] && (alen[j]+1)>alen[i]){
alen[i]=alen[j]+1;
ac[i]=ac[j];
}
if(b[j]<a[i] && (blen[j]+1)>alen[i]){
alen[i]=blen[j]+1;
ac[i]=bc[j];
}
}
blen[i]=1;
bc[i]=1;
for(int j=0;j<i;j++){
if(a[j]<b[i] && (alen[j]+1)>blen[i] && ac[j]<m){
blen[i]=alen[j]+1;
bc[i]=ac[j]+1;
}
if(b[j]<b[i] && (blen[j]+1)>blen[i] && bc[j]<m){
blen[i]=blen[j]+1;
bc[i]=bc[j]+1;
}
}
}
int max=alen[0];
for(int i=0;i<n;i++){
if(max<alen[i]) max=alen[i];
if(max<blen[i]) max=blen[i];
}
cout<<max<<endl;
}
return 0;
}
/// 2 6 3 5 1 4 2 3 1 2 4 3 1 4 5