1. 程式人生 > >2017 ICPC區域賽(西安站)--- J題 LOL(DP)

2017 ICPC區域賽(西安站)--- J題 LOL(DP)

nds 我們 要求 tle 思路 strings padding back 全排列

題目鏈接

problem description

5 friends play LOL together . Every one should BAN one character and PICK one character . The enemy should BAN 55 characters and PICK 55 characters . All these 2020 heroes must be different .

Every one can BAN any heroes by his personal washes . But he can only PICK heroes which he has bought .

Suppose the enemy can PICK or BAN any heroes. How many different ways are there satisfying the conditions?

For example , a valid way is :

Player 11 : picks hero 11, bans hero 22

Player 22 : picks hero 33, bans hero 44

Player 33 : picks hero 5, bans hero 66

Player 44 : picks hero 77, bans hero 88

Player 55 : picks hero 99, bans hero 1010

Enemies pick heroes 11,12,13,14,1511,12,13,14,15 , ban heroes 16,17,18,19,2016,17,18,19,20 .

Input

The input contains multiple test cases.(No more than 2020)

In each test case . there’s 55 strings S[1] \sim S[5]S[1]S[5] ,respectively whose lengths are 100100 , For the ii-th person if he has bought the jj-th hero, the jj-th character of S[i]S[i] is ‘11‘, or ‘00‘ if not. The total number of heroes is exactly 100100 .

Output

For each test case , print the answer mod 10000000071000000007 in a single line .

樣例輸入

0110011100011001001100011110001110001110001010010111111110101010010011010000110100011001001111101011
1000111101111110110100001101001101010001111001001011110001111110101000011101000001011100001001011010
0100101100011110011100110110011100111100010010011001111110101111111000000110001110000110001100001110
1110010101010001000110100011101010001010000110001111111110101010000000001111001110110101110000010011
1000010011111110001101100000101001110100011000111010011111110110111010011111010110101111011111011011

樣例輸出

515649254

題目來源

ACM-ICPC 2017 Asia Xi‘an

題意:題意說的很亂,簡單來說就是輸入5個長為100的‘0’ ‘1’字符串,要求從每一行中取出一個‘1’ 但是這5個‘1’得在不同的列,求有多少種取法? 註意輸出的結果乘以常數tmp=531192758

思路:我們可以用DP解決這個問題,dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod 保證當前行取得一個‘1’ 是在前一行的‘1’的後面,然後把這5行字符串用全排列顛倒順序即可,把所有排列順序下的dp值dp[5][100]求和即可

這題正解是狀壓DP復雜度O(n)=2^5*500, 我上面的DP復雜度O(n)=5!*500, 這題現場賽的時候大多數人是暴力過的,唉~ 當時我傻了,DP想了一半覺得不太可行,賽後又想了想可行,比賽的時候壓力有點大,有點緊張,特別是最後半個小時。

代碼如下:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
char s[6][105];
LL dp[6][105],ans;

void Backtrack(int t)
{
    if(t==5)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=100;i++)
        {
            dp[1][i]=dp[1][i-1];
            if(s[1][i]==1) dp[1][i]++;
        }
        for(int i=2;i<=5;i++)
        {
            for(int j=1;j<=100;j++)
            {
                dp[i][j]=dp[i][j-1];
                if(s[i][j]==1) dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod;
            }
        }
        ans=(ans+dp[5][100])%mod;
        return ;
    }
    for(int i=t;i<=5;i++)
    {
        swap(s[i],s[t]);
        Backtrack(t+1);
        swap(s[i],s[t]);
    }
}

int main()
{
    LL tmp=531192758; /// 常數 tmp=A(95,5)*C(90,5)*C(85,5);
    while(scanf("%s",s[1]+1)!=EOF)
    {
        for(int i=2;i<=5;i++) scanf("%s",s[i]+1);
        ans=0;
        Backtrack(1);
        printf("%lld\n",ans*tmp%mod);
    }
    return 0;
}

2017 ICPC區域賽(西安站)--- J題 LOL(DP)