HDU 6327&&18多校訓練3I 【DP】
阿新 • • 發佈:2019-02-04
Problem I. Random SequenceTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 56 Accepted Submission(s): 13 Problem Description There is a positive integer sequence a1,a2,...,an with some unknown positions, denoted by 0. Little Q will replace each 0 by a random integer within the range [1,mLittle Q is wondering what is the expected value of this sequence. Please write a program to calculate the expected value. Input The first line of the input contains an integer T In each test case, there are 2 integers n,m(4≤n≤100,1≤m≤100) in the first line, denoting the length of the sequence and the bound of each number. In the second line, there are n integers a1,a2,...,an(0≤ai≤m), denoting the sequence. In the third line, there are m Output For each test case, print a single line containing an integer, denoting the expected value. If the answer is AB, please print C(0≤C<109+7) where A≡C×B(mod109+7). Sample Input 2 6 8 4 8 8 4 6 5 10 20 30 40 50 60 70 80 4 3 0 0 0 0 3 2 4 Sample Output 8000 3 Source |
題意:給定陣列a,如果ai為0則小明從1到m中隨機選擇一個數。求的期望值。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
int p[110][110],a[110],l[110],r[110];
LL dp[2][101][101][101];
LL v[110];
vector<int> di[110];
LL pod(LL x,LL n,LL MOD)
{
LL ret=1;
while(n)
{
if(n&1)ret=ret*x%MOD;
n>>=1;
x=x*x%MOD;
}
return ret;
}
int main()
{
for(int i=1; i<=100; i++)
for(int j=1; j<=100; j++)
p[i][j]=__gcd(i,j);
for(int i=1; i<=100; i++)
for(int j=i; j<=100; j+=i)
di[j].push_back(i);
int TA;
scanf("%d",&TA);
while(TA--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(a[i]==0)
{
l[i]=1;
r[i]=m;
}
else
{
l[i]=a[i];
r[i]=a[i];
}
}
for(int i=1; i<=m; i++)scanf("%lld",&v[i]);
memset(dp,0,sizeof(dp));
int w=0;
for(int i=l[3]; i<=r[3]; i++)
{
for(int j=l[2]; j<=r[2]; j++)
{
for(int k=l[1]; k<=r[1]; k++)
{
dp[w][i][p[i][j]][p[p[i][j]][k]]++;
}
}
}
for(int i=3; i<n; i++)
{
for(int x=1; x<=m; x++)
{
for(int y,yy=0; yy<di[x].size(); yy++)
{
y=di[x][yy];
for(int z,zz=0; zz<di[y].size(); zz++)
{
z=di[y][zz];
if(dp[w][x][y][z]==0)continue;
for(int j=l[i+1]; j<=r[i+1]; j++)
{
(dp[w^1][j][p[j][x]][p[j][y]]+=(dp[w][x][y][z]*v[p[j][z]])%MOD)%=MOD;
}
dp[w][x][y][z]=0;
}
}
}
w^=1;
}
LL ans=0;
for(int x=1; x<=100; x++)
{
for(int y,yy=0; yy<di[x].size(); yy++)
{
y=di[x][yy];
for(int z,zz=0; zz<di[y].size(); zz++)
{
z=di[y][zz];
ans=(ans+dp[w][x][y][z])%MOD;
}
}
}
LL tem=pod(m,MOD-2,MOD);
for(int i=1; i<=n; i++)
if(a[i]==0)
ans=ans*tem%MOD;
printf("%lld\n",ans);
}
}