疑问
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
int a[MAXN];
int dp[MAXN];
//喜欢的颜色
int f[210];
//喜欢颜色的数值大小
int ref[210];
int n;
//检查颜色是否是Eva喜欢的颜色
bool check[210];
//记录Eva喜欢的颜色的数量
int m=0;
//colors on the stripes
int l=0;
//有效的颜色数量
int p=0;
bool cmp(int l,int r){
if(ref[l] <= ref[r]){
return true;
}else{
return false;
}
}
int main(){
scanf("%d",&n);
//初始化
fill(ref,ref+210,-1);
//最长不下降序列最小值为1
fill(dp,dp+MAXN,1);
//读入Eva喜欢的颜色序列
char c;
scanf("%d",&m);
for(int i;i<m;++i){
scanf("%d%c",&f[i],&c);
ref[f[i]] = i;
check[f[i]] = true;
}
scanf("%d",&l);
for(int i=0;i<l;++i){
int now;
scanf("%d%c",&now,&c);
if(check[now]){
a[p] = now;
p++;
}
}
int ans=1;
for(int i=0;i<p;++i){
for(int j=0;j<i;++j){
if(cmp(a[j],a[i]) && dp[j]+1 > dp[i]){
dp[i] = dp[j] + 1;
}
}
if(dp[i] > ans){
ans = dp[i];
}
}
printf("%d",ans);
return 0;
}
反思
- LIS的题目,直接套模板就可以;
- 粗心的地方是没有看清楚题目,给自己一个硬性规定:必须一字一句看清题目,而且必须看两遍!!!
- 直接使用HashTable会更好,不要转来转去。《算法笔记》的代码如下(ps,为什么我上面的代码那么丑,呜呜呜😟):
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxc = 210; //最大颜色数
const int maxn = 10010; //最大L
int HashTable[maxc]; //将喜欢的颜色序列映射成递增序列,不喜欢的颜色映射为-1
int A[maxn],dp[maxn]; //最长不下降子序列的原数组A和DP数组
int main(){
int n,m,x;
scanf("%d%d",&n,&m); //其实n用不到
fill(HashTable,HashTable+maxc,-1);
for(int i=0;i<m;++i){
scanf("%d",&x);
HashTable[x] = i; //将喜欢的颜色按顺序映射成递增序列0,1,2...
}
int L,num=0; //num存放颜色序列中Eva喜欢的颜色的总数
scanf("%d",&L);
for(int i=0;i<L;i++){
scanf("%d",&x);
if(HashTable[x] >=0 ){ //若是喜欢的颜色,则加到A数组中
A[num++] = HashTable[x];
}
}
//以下全部为LIS问题的模板
int ans = -1;
for(int i=0;i<num;++i){
dp[i] = 1;
for(int j=0;j<i;++j){
if(A[j] <= A[i] && dp[i] < dp[j] + 1){
dp[i] = dp[j] + 1;
}
}
ans = max(ans,dp[i]);
}
printf("%d\n",ans);
return 0;
}
- LCS版本
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
const int maxc = 210;
int dp[MAXN][MAXN];
int a[maxc];
int b[MAXN];
int main(){
int n;
scanf("%d",&n);
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
}
int l;
scanf("%d",&l);
for(int j=1;j<=l;j++){
scanf("%d",&b[j]);
}
for(int i=0;i<=l;i++){
dp[0][i] = 0;
}
for(int i=0;i<=m;i++){
dp[i][0] = 0;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=l;j++){
if(a[i] == b[j]){
dp[i][j] = max(dp[i][j-1],dp[i-1][j])+1;
}else{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
printf("%d",dp[m][l]);
return 0;
}
注意状态转移方程在a[i] == b[j]
的写法~~~