1045 Favorite Color Stripe (30分)
这个题很明显是道DP题,因为这题看着很明显是动态的。
看下数据范围,喜欢的颜色是200,条带长度是10000,那么就是2e6,空间就确定了,状态方程就很容易确定。
定义dp[i][j]为当下标为i时,挑选的上一个喜欢的颜色为j时的最大长度。
那么dp方程就很好确定了。
如果下标为i的颜色时喜欢的颜色,那么,dp[i][j]=max(dp[i-1][k],dp[i][j]); k是允许放在j左边的颜色,包括颜色i。
如果不是就,复制上一层的状态给当前i就可以了。
#include <bits/stdc++.h>
using namespace std;
int a[10009],dp[10009][209];
int vis[209],b[209],le[209][209];
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
#endif
int N,M,L;
scanf("%d",&N);
scanf("%d",&M);
for (int i=1;i<=M;i++) {
scanf("%d",&b[i]);
vis[b[i]]=1;
for (int j=1;j<=i;j++) {
le[b[i]][b[j]]=1;
}
}
scanf("%d",&L);
for (int i=1;i<=L;i++) {
scanf("%d",&a[i]);
if (vis[a[i]]) {
int mx=0;
for (int j=1;j<=M;j++) {
int k=b[j];
dp[i][k]=dp[i-1][k];
if (le[a[i]][k]) mx=max(mx,dp[i-1][k]);
}
dp[i][a[i]]=mx+1;
} else {
for (int j=1;j<=M;j++) {
int k=b[j];
dp[i][k]=dp[i-1][k];
}
}
// for (int j=1;j<=M;j++) {
// int k=b[j];
// printf("%d ",dp[i][k]);
// }
// putchar('\n');
}
int ans=0;
for (int i=1;i<=M;i++) ans=max(ans,dp[L][b[i]]);
printf("%d\n",ans);
return 0;
}