B - Problem Arrangement ZOJ - 3777

Problem Arrangement ZOJ - 3777

  题目大意:有n道题,第i道题第j个做可以获得Pij的兴趣值,问至少得到m兴趣值的数学期望是多少,如果没有的话就输出No solution。

  数学期望很好求,求出符合的方案数与总方案之比就是概率,概率的倒数就是期望。问题在于怎么安排这些题目的做题顺序,如果直接暴力的话,有12!种情况,铁定超时,所以我们可以转换成dp的思想,总共就是12道题,也就212-1种状态,我们枚举每个状态得多少分时的方案数,最终符合的方案数就是dp[212-1][m]。然而重点在于怎么表示这个状态,以及转移。我想的是二进制对应的第i位是0或者1就代表第i个题安排了没有,但是这样的话转移的时候就是要4重循环,果断超时。而观摩了qxdywjy的代码后,状态表示是二进制对应的第i位是0或者1就代表第i道题做了,这样状态的转移就只有用三重循环了,转移就是遍历所有状态,状态i如果第j题没做,那么转移到i|(1<<j)状态中,它就是是第num个做,num就是已经做了多少道题。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int dp[(1<<12)+10][520],a[15][15],cf2[15],jc[15];
 5 int main()
 6 {
 7     cf2[0]=jc[0]=1;
 8     for(int i=1;i<=12;i++)
 9     {
10         cf2[i]=cf2[i-1]<<1;
11         jc[i]=jc[i-1]*i;
12     }
13     int t,n,m;
14     scanf("%d",&t);
15     while(t--)
16     {
17         scanf("%d%d",&n,&m);
18         for(int i=0;i<cf2[n];i++)
19             for(int j=0;j<=m;j++)
20                 dp[i][j]=0;
21         for(int i=0;i<n;i++)
22             for(int j=0;j<n;j++)
23                 scanf("%d",&a[i][j]);
24         dp[0][0]=1;
25         for(int i=0;i<cf2[n];i++)
26         {
27             int num=0;//num已经做了几道题
28             for(int j=0;j<n;j++)
29                 if(i&cf2[j])
30                     num++;
31             for(int j=0;j<n;j++)
32                 if(!(i&cf2[j]))//如果第j题还没做
33                 {
34                     for(int k=0;k<=m;k++)
35                     {
36                         int lim=min(m,k+a[j][num]);//多于m就算m,节省空间
37                         dp[i|cf2[j]][lim]+=dp[i][k];
38                     }
39                 }
40         }
41         int ans1=jc[n],ans2=dp[cf2[n]-1][m];
42         if(ans2==0)
43             printf("No solution\n");
44         else
45         {
46             int g=__gcd(ans1,ans2);
47             printf("%d/%d\n",ans1/g,ans2/g);
48         }
49     }
50     return 0;
51 } 

状压呀

原文地址:https://www.cnblogs.com/LMCC1108/p/10749613.html

时间: 2024-11-06 09:36:33

B - Problem Arrangement ZOJ - 3777的相关文章

2014 Super Training #4 B Problem Arrangement

原题:ZOJ 3777  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 题意:给每个题目安排在每个位置的value.有一个程序随机选择安排的顺序,总的value值大于等于m时,就可以接受这个安排.问能够获得一次满足条件的安排的期望次数. 这题不会做,看网上是用状态压缩DP做的. 定义: dp[i][j]为选取了前i行,趣味和为j的方案种数. 由于程序是每次随机选择一个排列,每次的选择之间不影响,而且每次选中的概

ZOJ 3777 Problem Arrangement(状压DP)

题目链接 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5264 //今年省赛的题目,比赛的时候知道是状压却一直没搞出,直到最后.虽然赛后知道做法,也一直没做的,最近想不开就来做了 - -, 顺便用了下快速枚举k-子集. 恩, 做法么就是开dp[i][j] i已经选过了的题目的一个集合,j表示的是获得了j分,然后就可以直接做了..(但是好像说会T或者卡空间,我的做法是快速枚举k-子集,这个东西可以看下watashi翻译的

zoj 3777 Problem Arrangement

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5264 题意:给出n道题目以及每一道题目不同时间做的兴趣值,让你求出所有做题顺序中兴趣值大于等于m的比例.用一个分数表示. 状压dp. 枚举每一个状态,用二进制表示.dp[i][j]表示第i个题目,兴趣值为j的个数. 转移方程 dp[i|(1<<j)][k+a[num][j]]+=dp[i][k];兴趣值大于m的为 dp[1|(1<<j)][m]+=dp[i][k

ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树)

题目链接  ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. 所以开$48$棵线段树,和一个永久标记.当对某个区间操作时对这个区间加一层永久标记. 即当前我要查找的第$x$层,实际找的是第$up[i] + x$层. 时间复杂度$O(48nlogn)$ #include <bits/stdc++.h> using namespace std; #define

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

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int dp[1<<13][510],map[13][13];int m,n;int gcd(long long a,long long b){ if(b!=0) return gcd(b,a%b); return a;}int main(){ int T; scanf("%d",&T

ZOJ 刷题记录 (??ω?)??

P1002:简单的DFS 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 char map[5][5]; 6 int N; 7 8 int input() 9 { 10 scanf("%d",&N); 11 for(int i=0;i<N;i++) scanf("%s",map[i]); 12 return N; 13 } 14

浙大计算机研究生复试上机考试-2010年 zoj问题

ZOJ问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2984 Accepted Submission(s): 906 Problem Description 对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC. 是否AC的规则如下: 1. zoj能AC: 2. 若字符串形式为xzojx,则也能AC,其中x可以是N

UVA524 素数环 Prime Ring Problem

题目OJ地址: https://www.luogu.org/problemnew/show/UVA524 hdu oj 1016:  https://vjudge.net/problem/HDU-1016 zoj 1457  :https://vjudge.net/problem/ZOJ-1457 题意翻译 输入正整数n,把整数1,2,...,n组成一个环,使得相邻两个整数之和均为素数.输出时,从整数1开始逆时针排列.同一个环恰好输出一次.. 多组数据,读入到EOF结束. 第i组数据输出前加上一

L - Median(ZOJ 4124)

Time Limit : 1 Second      Memory Limit : 65536 KB Source : 第十届山东省ACM省赛 Problem Link : ZOJ 4124 Author : Houge Date : 2019-5-19 题目大意: 给你n个数(不知道谁大谁小)和m个关系(ai,bi),每个关系代表ai严格大于bi.问你能否通过已知推出可能的中间项k的位置.(题目保证n一定是奇数) 分析: 比赛时想用拓扑排序,结果因为菜没写出来,赛后听了学长用floyd的思路,