CUGOJ 1437 Take Photo

来源:互联网 发布:ubuntu安装apache php 编辑:程序博客网 时间:2024/05/21 11:01

题目

Description

There are n people standing in a line to take photo. But for some reasons ,there are some limits on their positions. For example, i must stand on j’s right, marked for (i, j). Now, giving you the n people and those limits, please tell me the number of the legal permutation.

Input

There are multiple test cases. For each test:
The first line contains one positive integer n (1<=n<=16), indicating the number of people. Then following there are n lines, each line containing n integers. The element at ith row and jth column is either 1 or 0; if the element is 1, it represents the limit (i, j); You can assume that any pair of (i, j) is bound to be 0 if i is equal to j.
Processed to the end of file.

Output

 For each test case, output the number of legal permutation on one line.

Sample Input

2
0 1
1 0
3
0 0 0
0 0 0
0 0 0
3
0 0 0
1 0 0
0 1 0

Sample Output

0
6
1


状态dp,类似于棋盘问题,加上一些限制,状态i中1的个数表示已经安排了几个人,并且放在了哪些行,


// http://acm.cug.edu.cn/JudgeOnline/problem.php?id=1437#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;ll dp[1<<16];int n;int map[17][17];int num1[17],num2[17],num3[17],num4[17];inline int getone(int i){    int cnt=0;    while(i) cnt+=i%2,i>>=1;    return cnt;}int main(){    while(~scanf("%d",&n))    {        memset(num1,0,sizeof(num1));        memset(num3,0,sizeof(num3));        memset(num4,0,sizeof(num4));        memset(num2,0,sizeof(num2));        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)            {                scanf("%d",&map[i][j]);            }        int tag=1;        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)                if(i!=j)                {                    if(map[i][j]&&map[j][i]) tag=0;break;                }        if(!tag)        {            puts("0");            continue;        }        for(int i=0;i<n;i++)        {            for(int j=0;j<i;j++)            {                if(map[j][i]) num1[i]++;//在0~i人中有多少个人必须在i的右边                if(map[i][j]) num2[i]++;//在0~i人中有多少个人必须在i的左边            }        }        for(int i=0;i<n;i++)        {            for(int j=i+1;j<n;j++)            {                if(map[j][i]) num3[i]++;//在i+1~n-1人中。。。。。                if(map[i][j]) num4[i]++;//。。。。            }        }        int all=(1<<n)-1;        memset(dp,0,sizeof(dp));        dp[0]=1;        for(int i=1;i<=all;i++)        {            int rr=getone(i)-1;            ll ans=0;            for(int j=0;j<n;j++)            {                if(i&(1<<j))                {                    int l=0,r=0,ll=0,rrr=0;                    for(int k=0;k<j;k++)                        (i&(1<<k))?l++:ll++;                    for(int k=j+1;k<n;k++)                        (i&(1<<k))?r++:rrr++;                    if(r<num1[rr]) continue;                    if(l<num2[rr]) continue;                    if(rrr<num3[rr]) continue;                    if(ll<num4[rr]) continue;                    ans+=dp[i&(~(1<<j))];                }            }            dp[i]=ans;        }        printf("%lld\n",dp[all]);    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脚趾头冻了很痒怎么办 大脚趾里面有脓怎么办 大脚趾肉肿了怎么办 大脚趾边上肿了怎么办 大母脚趾关节疼怎么办 大脚趾有点歪了怎么办 大脚趾扭伤肿了怎么办 大脚趾外翻怎么办 知乎 颈椎带着胳膊疼怎么办 胳膊酸困无力是怎么办 腰疼引起的腿麻怎么办 手臂到手指麻痛怎么办 拔完智齿特别疼怎么办 躺着胃烧的难受怎么办 喝酒胃烧的难受怎么办 舌头破了特别疼怎么办 舌头又厚又大怎么办 牙齿咬到舌头了怎么办 舌头起了好多泡怎么办 舌头尖起泡很痛怎么办 舌头上起泡怎么办很疼 月经来了二十多天还不干净怎么办 三岁宝宝缺锌怎么办 无舌苔,舌头很红怎么办 嘴唇上肿了一块怎么办 下嘴唇突然肿了怎么办 上嘴唇突然肿厚怎么办 舌尖上火了好疼怎么办 舌头针扎似的疼怎么办 手麻了怎么办小妙招 月子生气奶少了怎么办 颈椎会引起脸麻怎么办 脑梗引起的手麻怎么办 着凉引起的腰疼怎么办 受凉引起的腰疼怎么办 着凉了腰疼厉害怎么办 腰疼压迫神经腿麻木怎么办 运动后小腿变粗怎么办 跑步后小腿变粗怎么办 嘴腮里面肉肿了怎么办 左胳膊左腿发麻怎么办