题解

1 条题解

  • 0
    @ 2017-10-05 14:57:02

    考试的时候其实思路大概是正解,写出来怎么也有六十分吧。把数据散列掉,再进行类似于二维背包的操作,并且把所有大于m的数都散列未m。
    理想虽丰满,还是爆内存。待到成绩爆零时,钻石丛中笑。
    #include<bits/stdc++.h>
    const int maxn=31;
    inline const void read(int &a)
    {
    a=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')
    {
    a=(a<<1)+(a<<3)+c-'0';
    c=getchar();
    }
    }
    inline const void write(int a)
    {
    if(a>9)write(a/10);
    putchar(a%10+'0');
    }
    int n,m,v[maxn];
    double p[maxn],f[2][maxn][50000];
    int hash[10000000],ex_hash[50000];
    int main()
    {
    read(n);read(m);
    for(int i=1;i<=n;i++)
    {
    int o;
    read(v[i]);read(o);
    p[i]=double(o)/100;
    }
    memset(ex_hash,0,sizeof(ex_hash));
    memset(hash,0,sizeof(hash));
    memset(f,0,sizeof(f));
    int d=-1,x=0;
    hash[0]=++d;ex_hash[d]=0;
    hash[m]=++d;ex_hash[d]=m;
    f[x][0][0]=1;
    for(int i=1;i<=n;i++)
    {
    x^=1;
    for(int j=0;j<=i;j++)
    for(int k=0;k<=d;k++)
    {
    int r=ex_hash[k]+v[i];
    if(!hash[r])
    {
    if(r<m){hash[r]=++d;ex_hash[d]=r;}
    else r=m;
    }
    if(j)f[x][j][k]+=f[x^1][j-1][k]*(1.0-p[i]);
    f[x][j][hash[r]]+=f[x^1][j][k]*p[i];
    }
    }
    for(int i=0;i<=n;i++)printf("%.3lf\n",f[x][i][hash[m]]);
    return 0;
    }

    正解,注意可以bfs,然后在中间合并。原来的复杂度为O(n^30),现在的复杂度为O(2n^15)也就是O(N^16),这就能在一秒以内搜出来了。
    #include<cstdio>
    #include<cmath>
    using namespace std;
    double k[40]={0},f[40][40]={0};
    int cnt=0,n,m,i,j,v[40],p[40];
    int ss(int t,double l,int s,int q)
    {
    if(s>=m)return 0;
    if(t==n+1)
    {
    if(s<m)f[n][q]-=l;
    return 0;
    }
    ss(t+1,l*p[t]/100.0,s+v[t],q);
    ss(t+1,l*(100-p[t])/100.0,s,q+1);
    return 0;
    }
    int main()
    {
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    scanf("%d%d",&v[i],&p[i]);
    f[1][0]=p[1]/100.0;
    f[1][1]=(100-p[1])/100.0;
    for(i=2;i<=n;i++)
    for(j=0;j<=i;j++)
    {
    if(j)f[i][j]+=f[i-1][j-1]*(100-p[i])/100.0;
    f[i][j]+=f[i-1][j]*(p[i]/100.0);
    }
    ss(1,1,0,0);

    for(i=0;i<=n;i++)
    printf("%.3lf\n",f[n][i]);
    return 0;
    }

  • 1

信息

难度
9
分类
(无)
标签
(无)
递交数
3
已通过
1
通过率
33%
上传者