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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

状态压缩dp入门 (poj3254 Corn Fields)

题目链接:http://poj.org/problem?id=3254 题意:给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多...
  • y990041769
  • y990041769
  • 2014年04月28日 19:10
  • 18968

TSP问题之状态压缩dp法

动态规划的状态有时候比较难,不容易表示出来,需要用一些编码技术,把状态压缩,用简单的方式表示出来。典型方式就是当需要表示一个集合有哪些元素时,往往利用2进制用一个整数表示。一般数据n...
  • qq_32400847
  • qq_32400847
  • 2016年07月03日 10:44
  • 2019

状态压缩DP与TSP问题

状态压缩DPDP过程中的状态不可能像背包问题一样只有整数,肯定有各种各样稀奇古怪的状态,需要不止一个变量来表示。这种情况下如果需要使用DP 就必须把状态压缩成一个数来表示,并且一个数只能对应于一种状态...
  • Area_52
  • Area_52
  • 2015年05月25日 10:58
  • 1525

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

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i...
  • Kirito_Acmer
  • Kirito_Acmer
  • 2016年02月24日 10:48
  • 300

ZOJ3777 - Problem Arrangement(状压DP)

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

ZOJ 3777 - Problem Arrangement(状压DP)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5264 题意: 给出n*n的矩阵,从中选出n个数,任意两个数在不同...
  • u013534690
  • u013534690
  • 2015年05月16日 12:15
  • 430

【ZOJ3777】Problem Arrangement(状压dp)

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

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

思路来源:http://blog.csdn.net/u013081425/article/details/23677585
  • hntyzhangpeng
  • hntyzhangpeng
  • 2014年08月07日 17:03
  • 828

zoj3777 Problem Arrangement(状态压缩dp)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 题意:给出n道题目以及每一道题目不同时间做的兴趣...
  • y990041769
  • y990041769
  • 2014年04月19日 21:20
  • 2670

Problem Arrangement ZOJ - 3777

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i...
  • qq_33362864
  • qq_33362864
  • 2017年01月16日 12:13
  • 140
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZOJ 3777 Problem Arrangement (状压DP)
举报原因:
原因补充:

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