【DP】poj1692

来源:互联网 发布:linux下路由跟踪命令 编辑:程序博客网 时间:2024/06/05 14:17

题意:对两个数列找一些匹配满足对于任意一个匹配有且仅有一个与其数字不同的匹配与之交叉。

一开始觉得应该是个n^4的,结果想一想发现每次更新的时候,如果a[i]!=b[j]那每次在b里找最近的一个数等于a[i]然后在a里找最近的一个等于b[j]就好,也算是一种贪心的思想,想想,如果再往前找的话肯定不如最近的优于是就是n^3了

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>using namespace std;int n1,n2,dp[210][210],a[210],b[210],m;int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);scanf("%d",&m);while (m--){memset(dp,0,sizeof(dp));scanf("%d%d",&n1,&n2);for (int i=1;i<=n1;i++)scanf("%d",&a[i]);for (int i=1;i<=n2;i++)scanf("%d",&b[i]);for (int i=1;i<=n1;i++)for (int j=1;j<=n2;j++){int k1,k2;dp[i][j]=max(dp[i-1][j],max(dp[i][j-1],dp[i-1][j-1]));if (a[i]!=b[j]){for (k1=i-1;k1;k1--)if (a[k1]==b[j])break;for (k2=j-1;k2;k2--)if (b[k2]==a[i])break;if (k1&&k2) dp[i][j]=max(dp[i][j],dp[k1-1][k2-1]+2);}}printf("%d\n",dp[n1][n2]);}return 0;}

0 0