一道题7

Posted blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道题7相关的知识,希望对你有一定的参考价值。

$n \leq 40$个数字初始为0,$m \leq 10$次操作每次以给定概率$P(i,j,k)$选择二元组$(j,k)$,表示第$j$个数加上$k$,$0 \leq k \leq C \leq 3$,$C$是给定常数。问最后序列的期望最大值。

状压太菜要补啊。

以数字为切入点,把每个数字分开计算最后合起来。但是注意新加进一个数的转移不能单看这个数的值的概率,还要看操作。因此把操作表示进状态。

$f(i,j,k)$--前$i$个数,操作集合$j$时,最大值$k$的概率。$g(i,j,k)$--第$i$个数,操作集合$j$时,值为$k$的概率。转移略。

技术分享图片
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 //#include<queue>
 5 //#include<vector>
 6 #include<algorithm>
 7 //#include<iostream>
 8 //#include<assert.h>
 9 using namespace std;
10 
11 int n,m,c;
12 #define LL long long
13 LL f[2][1111][35],sf[1111][35],g[1111][35],sg[1111][35]; int cur,p[11][44][5],sp[44];
14 const int mod=1e9+7;
15 int main()
16 {
17     scanf("%d%d%d",&n,&m,&c);
18     for (int i=1;i<=n;i++) sp[i]=1;
19     for (int i=1;i<=m;i++) for (int j=1;j<=n;j++)
20     {
21         int tot=0;
22         for (int k=0;k<=c;k++)
23         scanf("%d",&p[i][j][k]),tot+=p[i][j][k],tot-=tot>=mod?mod:0;
24         sp[j]=1ll*sp[j]*(mod+1-tot)%mod;
25     }
26     
27     cur=0; f[0][0][0]=1; int tot=m*c;
28     for (int i=1;i<=n;i++)
29     {
30         for (int j=0;j<(1<<m);j++)
31         {
32             sf[j][0]=f[cur][j][0];
33             for (int k=1;k<=tot;k++) sf[j][k]=sf[j][k-1]+f[cur][j][k],sf[j][k]-=sf[j][k]>=mod?mod:0;
34         }
35         memset(g,0,sizeof(g)); g[0][0]=1;
36         for (int j=0;j<(1<<m);j++)
37         {
38             int tmp=0;
39             for (int k=1;k<=m;k++) if (((j>>(k-1))&1)==1) tmp=k;
40             for (int k=tmp+1;k<=m;k++)
41             {
42                 int s=j|(1<<(k-1));
43                 for (int t=0,to=tot;t<=to;t++)
44                     for (int l=0;l<=c;l++)
45                         g[s][t+l]+=g[j][t]*1ll*p[k][i][l]%mod,g[s][t+l]-=g[s][t+l]>=mod?mod:0;
46             }
47         }
48         for (int j=0;j<(1<<m);j++)
49         {
50             sg[j][0]=g[j][0];
51             for (int k=1;k<=tot;k++) sg[j][k]=sg[j][k-1]+g[j][k],sg[j][k]-=sg[j][k]>=mod?mod:0;
52         }
53         
54         for (int j=0;j<(1<<m);j++)
55         {
56             int fj=(1<<m)-j-1;
57             for (int s=fj;;s=(s-1)&fj)
58             {
59                 for (int k=1;k<=tot;k++) f[cur^1][j|s][k]+=f[cur][j][k]*1ll*sg[s][k-1]%mod,
60                 f[cur^1][j|s][k]-=f[cur^1][j|s][k]>=mod?mod:0;
61                 for (int k=0;k<=tot;k++) f[cur^1][j|s][k]+=sf[j][k]*1ll*g[s][k]%mod,
62                 f[cur^1][j|s][k]-=f[cur^1][j|s][k]>=mod?mod:0;
63                 if (s==0) break;
64             }
65         }
66         memset(f[cur],0,sizeof(f[cur]));
67         cur^=1;
68     }
69     
70     int ans=0;
71     for (int j=1,tmp=(1<<m)-1;j<=tot;j++) ans+=f[cur][tmp][j]*1ll*j%mod,ans-=ans>=mod?mod:0;
72     printf("%d\n",ans);
73     return 0;
74 }
View Code

 

以上是关于一道题7的主要内容,如果未能解决你的问题,请参考以下文章

一道经典面试题:字符串在Java中如何通过“引用”传递

每日一道算法题--两数之和

一道积分题的7种换元方法

7.13

每天一道Java题[7]

一道题7