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
Sample Output
状态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;}
- CUGOJ 1437 Take Photo
- Take Photo
- Take (and Manipulate!) a Photo with a Web Page
- CUGOJ 1682
- photo
- photo
- photo
- Photo
- photo
- photo
- photo
- photo
- take
- cugoj-1697梦回三国
- CUGOJ 1681 求解最长回文字符串
- ACM之搜索-DFS-cugoj-1149
- sniper photo
- Photo Properties
- 很幽默的讲解六种Socket IO模型(转)
- (Math Foundation 笔记)1.实数公理和用公理证明2
- 项目中发送短信--中国网建SMS短信通
- FOR ALL ENTRIES vs DB2 JOIN
- Oracle 11g的密码更新
- CUGOJ 1437 Take Photo
- Oracle SQL的优化
- 养成类手游数据逻辑
- hadoop学习(二)ubuntu下安装virtual box 问题与解决
- linux shell awk 语法
- From Galileo to Google: How Big Data Illuminates Human Culture
- windows RabbitMQ 安装环境配置
- *p,&p,p在c中的区别
- Spring Aop XML