ZOJ 3777 Problem Arrangement (状压DP)

原创 2015年11月19日 22:13:53

分析:题目要求数学期望,其实就是求最终值M的概率。暴力的做法:找出所有排列方式,一个一个找:o(12!),贵了。对数据敏感的话,应该比较容易想到状压。
dp[i][msk][j]代表前i个数用了msk状态的数,和为j的排列总数。
那么转移方程:

dp[i][msk][j]=mskk1dp[i1][msk|1<<k][jp[k][i]]

其实第一维根本没什么意义,msk1的个数就代表了i的值,所有可以把第第一维去掉:p
dp[msk][j]=mskk1dp[msk|1<<k][jp[k][cnt[msk]]]

代码:(由于角标是从0开始的,所以和上面的有点不太一样)

#include <bits/stdc++.h>
#define LL long long
#define FOR(i,x,y)  for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)

using namespace std;

typedef vector <int> VT;

const int maxn = 1<<12;
const int maxm = 550;

LL dp[maxn][maxm];

int p[12][12],cnt[maxn][13];

int n,m;

LL gcd(LL a,LL b){
    return b == 0 ? a : gcd(b,a%b);
}

int main()
{
    //freopen("test.in","r",stdin);
    FOR(i,0,maxn){
        cnt[i][0] = 0;
        FOR(j,0,12){
            if(i & (1<<j)){
                cnt[i][++cnt[i][0]] = j;
            }
        }
    }
    int T;  scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        FOR(i,0,n)
            FOR(j,0,n)  scanf("%d",&p[i][j]);
        dp[0][0] = 1;
        int MSK = 1<<n;
        FOR(i,0,m){
            FOR(msk,1,MSK){
                dp[msk][i] = 0;
                FOR(j,1,cnt[msk][0]+1){
                    int k = cnt[msk][j];
                    if(i < p[k][cnt[msk][0]-1])  continue;
                    dp[msk][i] += dp[msk^(1<<k)][i-p[k][cnt[msk][0]-1]];
                }
            }
        }
        LL sum = 1;
        FOR(i,1,n+1){
            sum *= i;
        }
        LL res = 0;
        FOR(i,0,m){
            res += dp[MSK-1][i];
        }
        res = sum - res;
        if(!res){
            printf("No solution\n");
            continue;
        }
        LL g = gcd(res,sum);
        res /= g;
        sum /= g;
        printf("%lld/%lld\n",sum,res);
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ZOJ3777 - Problem Arrangement(状压DP)

题目链接:https://cn.vjudge.net/problem/ZOJ-3777题目大意:现在有一个N×N的矩阵,现在要求在这个矩阵里面取N个来自不同行不同列的数,使这个数大于给定的M。求总共有...

ZOJ 3777 - Problem Arrangement(状压DP)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5264 题意: 给出n*n的矩阵,从中选出n个数,任意两个数在不同...

【ZOJ3777】Problem Arrangement(状压dp)

题目链接 题目大意: 有n道题,第i道题放在第j个有价值PijP_{ij} 有T组数据。 有n道题,给你一个价值m。 问有多少种方案使得总价值大于等于m。 输出方案数/总数(分数最简) ...

zoj3777 Problem Arrangement(状压dp,思路赞)

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i...

zoj-3777-Problem Arrangement(状态压缩DP)

思路来源:http://blog.csdn.net/u013081425/article/details/23677585

zoj3777 Problem Arrangement(状态压缩dp)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 题意:给出n道题目以及每一道题目不同时间做的兴趣...

Problem Arrangement ZOJ - 3777

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i...

ZOJ3777---Problem Arrangement

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i...

ZOJ3777 Problem Arrangement 期望+状态压缩+meet in the middle中途相遇法

Problem Arrangement Time Limit: 2 Seconds      Memory Limit: 65536 KB The 11th Zhejiang Provin...

zoj 3777 状压dp

Problem Arrangement Time Limit: 2 Seconds      Memory Limit: 65536 KB The 11th Zhejiang Provin...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZOJ 3777 Problem Arrangement (状压DP)
举报原因:
原因补充:

(最多只允许输入30个字)