TopCoder SRM 582 ColorfulBuilding

时间:2023-03-08 20:16:22

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]);
}
};