您的位置:首页 > 其它

SRM 554 div2

2012-09-02 02:20 323 查看
这场比赛还算顺利,唯一的遗憾就是1000pt没有弄出来,写之前没有考虑清楚,想到什么就写什么,导致错失AK良机,囧。。。。

250pt :

    水题,不解释

500pt:

   同上

1000pt :

题意:给你最多四种颜色的砖块,每种砖块有无限个(1*1*1的单位立方体),求拼成一个2*2*h(h<=H)的棱柱,并且相邻两块单位立方体颜色相同的对数小于等于K的总方案数

可以设计这样的状态来描述这个问题

dp[h][i][j][k][l][x]

依次表示高度 h,最上面的面的四个立方体的颜色(i,j,k,l),总共的颜色对数 x,也可以将四种颜色压缩成一个思维的二进制来做,我是直接开了六维了。

转移的时候很easy的,关键是设计好状态~

#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
typedef long long lld;
const int mod = 1234567891;
lld dp[50][4][4][4][4][8];
class TheBrickTowerHardDivTwo{
public :
int find(int n, int K, int H)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
for(int l=0;l<n;l++)
{
int tmp=(i==j)+(i==k)+(k==l)+(j==l);
if(tmp<=K) dp[1][i][j][k][l][tmp]=1;
}
for(int h=2;h<=H;h++)
for(int x=0;x<=K;x++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
for(int l=0;l<n;l++)
for(int a0=0;a0<n;a0++)
for(int a1=0;a1<n;a1++)
for(int a2=0;a2<n;a2++)
for(int a3=0;a3<n;a3++)
{
int tmp=(i==j)+(i==k)+(k==l)+(j==l)+(a0==i) +(a1==j)+(a2==k)+(a3==l);
if(x+tmp<=K && dp[h-1][a0][a1][a2][a3][x])
dp[h][i][j][k][l][x+tmp]=(dp[h-1][a0][a1][a2][a3][x]+dp[h][i][j][k][l][x+tmp])%mod;
}
lld ans=0;
for(int h=1;h<=H;h++)
for(int x=0;x<=K;x++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
for(int l=0;l<n;l++)
{
ans+=dp[h][i][j][k][l][x];
ans%=mod;
}
return (int)ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  div ini class