DP 思路是三维,但是时间肯定会超时,需要根据其特殊性质加两个标记数组,优化成二维。
刚开始想了N久N久,没感觉,还是动手画了一下才有用呀,意淫再久,不如动手呀。
代码:
#include<iostream> #include<cstdio> #include<vector> #include<stack> #include<cstring> #include<queue> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<set> #include<map> using namespace std; const int INF=0x3f3f3f3f; const long long MOD=1000000009; const int N=3000; const int M=2500; long long dp[N][M]; long long sum[M],a[N]; int getInt(char x) { if(x>='A'&&x<='Z') return x-'A'; return x-'a'+26; } int hashChartoInt(char x,char y) { return getInt(x)*52+getInt(y); } long long add(long long x,long long y) { long long s=x+y; if(s>=MOD) s-=MOD; return s; } long long sub(long long x,long long y) { long long s=x-y; if(s<=0) s+=MOD; return s; } long long mul(long long x,long long y) { return (x*y)%MOD; } class ColorfulBuilding { public: int count(vector <string> color1, vector <string> color2, int L) { memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); memset(a,0,sizeof(a)); string str1="",str2=""; for(unsigned int i=0;i<color1.size();++i) str1+=color1[i]; for(unsigned int i=0;i<color2.size();++i) str2+=color2[i]; int n=str1.size(); for(int j=0;j<N;++j) a[j]=1; for(int i=0;i<n;++i) { int nowColor=hashChartoInt(str1[n-i-1],str2[n-i-1]); if(i==0) { dp[nowColor][1]=1; sum[1]=1; continue; } for(int j=L;j>=1;--j) { dp[nowColor][j]=mul(dp[nowColor][j],a[nowColor]); sum[j]=mul(sub(sum[j],dp[nowColor][j]),i); dp[nowColor][j]=(dp[nowColor][j]*(i+1))%MOD; dp[nowColor][j]=add(dp[nowColor][j],sub(sum[j-1],mul(dp[nowColor][j-1],a[nowColor]))); sum[j]=add(sum[j],dp[nowColor][j]); } for(int j=0;j<N;++j) if(j==nowColor) a[j]=1; else a[j]=mul(a[j],i); } return (int)(sum[L]); } };