【Codeforces Round #418 (Div. 2)】Codeforces 814E An unavoidable detour for home

来源:互联网 发布:dota2职业选手 数据 编辑:程序博客网 时间:2024/06/10 14:51

把图按照最短路分层,那么这个图需要满足每个点都向上一层有且只有一条边,并且没有更向上的边。
我们用dp[u][i][j][k][l]表示前u个节点,上一层有i个读数为1的插头和j个度数为2的插头,这一层有k个度数为1的插头和l个度数为2的插头。注意我们甚至并不需要关心最短路到底是多少。大力讨论一下转移就可以了。当前点先和上一层的一个点连接,剩下的度数可以留下,也可以和这一层的随便连。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long long#define DP dp[c][j][k][x][y]const int p=1000000007;int d[55],n;LL dp[2][51][51][51][51];void upd(LL &x,LL y){    x+=y;    x%=p;}int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++) scanf("%d",&d[i]);    dp[0][d[1]==2][d[1]==3][d[2]==2][d[2]==3]=1;    for (int i=2,c=0;i<n;i++,memset(dp[c],0,sizeof(dp[c])),c^=1)        for (int j=0;j<=i;j++)            for (int k=0;j+k<=i;k++)                for (int x=0;j+k+x<=i;x++)                    for (int y=0;j+k+x+y<=i;y++)                        if (DP)                        {                            if (!j&&!k)                            {                                if (x||y) upd(dp[c][x][y][0][0],DP);                                continue;                            }                            if (d[i+1]==2)                            {                                if (j)                                {                                    upd(dp[c^1][j-1][k][x+1][y],DP*j);                                    if (x) upd(dp[c^1][j-1][k][x-1][y],DP*j*x);                                    if (y) upd(dp[c^1][j-1][k][x+1][y-1],DP*j*y);                                }                                if (k)                                {                                    upd(dp[c^1][j+1][k-1][x+1][y],DP*k);                                    if (x) upd(dp[c^1][j+1][k-1][x-1][y],DP*k*x);                                    if (y) upd(dp[c^1][j+1][k-1][x+1][y-1],DP*k*y);                                }                            }                            else                            {                                if (j)                                {                                    upd(dp[c^1][j-1][k][x][y+1],DP*j);                                    if (x) upd(dp[c^1][j-1][k][x][y],DP*j*x);                                    if (y) upd(dp[c^1][j-1][k][x+2][y-1],DP*j*y);                                    if (x>=2) upd(dp[c^1][j-1][k][x-2][y],DP*j*x*(x-1)/2);                                    if (x&&y) upd(dp[c^1][j-1][k][x][y-1],DP*j*x*y);                                    if (y>=2) upd(dp[c^1][j-1][k][x+2][y-2],DP*j*y*(y-1)/2);                                }                                if (k)                                {                                    upd(dp[c^1][j+1][k-1][x][y+1],DP*k);                                    if (x) upd(dp[c^1][j+1][k-1][x][y],DP*k*x);                                    if (y) upd(dp[c^1][j+1][k-1][x+2][y-1],DP*k*y);                                    if (x>=2) upd(dp[c^1][j+1][k-1][x-2][y],DP*k*x*(x-1)/2);                                    if (x&&y) upd(dp[c^1][j+1][k-1][x][y-1],DP*k*x*y);                                    if (y>=2) upd(dp[c^1][j+1][k-1][x+2][y-2],DP*k*y*(y-1)/2);                                }                            }                        }    printf("%I64d\n",dp[n&1][0][0][0][0]);}
原创粉丝点击