zoukankan      html  css  js  c++  java
  • [51Nod1850] 抽卡大赛

    link

    $solution:$

    朴素 $dp$,暴力枚举选择 $i$ 号人的第 $j$ 张卡片,朴素 $dp$ 即可,时间复杂度 $O(n^4)$ 。

    考虑对于朴素 $dp$ 的优化,发现其实是一个背包卷积的过程,考虑按 $A$ 值从大到小依次加入,每次维护新的 $P$ 值可以做到 $O(1)$ 。

    设计生成函数 $F(x)$ 表示将 $1-n$ 的所有多项式卷在一起的答案,每次只要维护多项式除法与乘法即可,而对于每个多项式都是形如 $ax+b$ 的形式,所以直接暴力维护即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define mod 1000000007
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=401;
    struct node{
        int val,id,res,p;
    }g[MAXN*MAXN];
    inline int ksm(int a,int b){
        int ans=1;
        while(b){
            if(b&1) ans*=a,ans%=mod;
            a*=a,a%=mod;
            b>>=1;
        }return ans;
    }
    int n,tot,F[MAXN],G[MAXN],p[MAXN];
    inline void mul(int x1,int x0){
        if(!x1) return;
        for(int i=0;i<=n;i++) G[i]+=F[i]*x0,G[i]%=mod,G[i+1]+=F[i]*x1,G[i+1]%=mod;
        for(int i=0;i<=n;i++) F[i]=G[i];memset(G,0,sizeof(G));return;
    }
    int Mod(int x){return ((x%mod)+mod)%mod;}
    inline void Div(int x1,int x0){
        if(!x1) return;int Inv=ksm(x1,mod-2);
        for(int i=n-1;i>=0;i--) G[i]=(Inv*F[i+1])%mod,F[i]=Mod(F[i]-x0*G[i]);
        for(int i=0;i<=n;i++) F[i]=G[i];memset(G,0,sizeof(G));return;
        return;
    }
    bool cmp(node x1,node x2){return x1.val>x2.val;}
    int P[MAXN],Ans[MAXN],v[MAXN];
    signed main(){
    //    freopen("51nod_1850_11_in.txt","r",stdin);
        n=read();int inv100=ksm(100,mod-2);
        for(int i=1;i<=n;i++){
            int num=read();
            int sum=0;
            int L=++tot,R=0;
            for(int j=1;j<=num;j++){
                g[++tot].id=i;
                g[tot].val=read(),g[tot].res=((100-read())*inv100)%mod,g[tot].p=read();
                sum+=g[tot].p;
                R=tot;
            }
            for(int j=L;j<=R;j++) g[j].p=(g[j].p*ksm(sum,mod-2))%mod;
        }
        for(int i=1;i<=n;i++) v[i]=read();
        F[0]=1;
        sort(g+1,g+tot+1,cmp);
        for(int i=1;i<=tot;i++){
            int id=g[i].id;
            Div(P[id],Mod(1-P[id]));
            P[id]+=g[i].p,P[id]=Mod(P[id]);P[id]=Mod(P[id]);
            for(int k=0;k<n;k++) Ans[id]+=Mod(Mod(Mod(F[k]*v[k+1])*g[i].res)*g[i].p),Ans[id]=Mod(Ans[id]);
            mul(P[id],Mod(1-P[id]));
        }
        for(int i=1;i<=n;i++) printf("%d
    ",Ans[i]);return 0;
    }
    View Code
  • 相关阅读:
    如何通过js在子页面调用父页面元素的click事件
    时间戳转换成时间格式
    sql 生成某个范围内的随机数
    Ioc思想
    【Sharepoint控件】MOSS模式化窗口
    【Sharepoint代码段】MOSS模拟超级管理员的方法
    【Sharepoint对象模型】MOSS根据模板添加子网站
    【Sharepoint控件】MOSS列表添加时SPUser字段赋值
    【C#代码段】asp在数据库加入数据
    【C#代码段】ajax从asp后台获取数据
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/11336235.html
Copyright © 2011-2022 走看看