# 2017 ICPC区域赛（西安站）--- J题 LOL（DP）

problem description

5 friends play LOL together . Every one should BAN one character and PICK one character . The enemy should BAN 5

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 1

Player 2

Player 3

Player 4

Player 5

Enemies pick heroes 11,12,13,14,15

### Input

The input contains multiple test cases.(No more than 20

In each test case . there’s 5

### Output

For each test case , print the answer mod 1000000007

#### 样例输入

0110011100011001001100011110001110001110001010010111111110101010010011010000110100011001001111101011
1000111101111110110100001101001101010001111001001011110001111110101000011101000001011100001001011010
0100101100011110011100110110011100111100010010011001111110101111111000000110001110000110001100001110
1110010101010001000110100011101010001010000110001111111110101010000000001111001110110101110000010011
1000010011111110001101100000101001110100011000111010011111110110111010011111010110101111011111011011

#### 样例输出

515649254

#### 题目来源

ACM-ICPC 2017 Asia Xi'an

这题正解是状压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;
}

posted @ 2018-01-21 13:36  茶飘香~  阅读(...)  评论(...编辑  收藏