Codeforces Round #157(完整)

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 

259A:每一行,wbwbwbwb,bwbwbwbw这两种情况是合法的


259B:SB了半天,题目只说了对角线是未知的,随意瞎搞吧,不知道什么好办法 


258A:被cha一次,注意全为1的情况,就是从高位判断,去掉第一个0,如果全为1,则随便去掉一位


258B:数位DP+DFS

数位DP处理出1---n含有i个lucky number的数有多少个

然后DFS每一个候选者选的种类,直接计数

一直不敢写,对于数位DP,没有把握,不过还好最后过了

LL dp[15][15];
void DP(){
    mem(dp,0);
    dp[0][0]=1;
    for(int i=0;i<10;i++){
        for(int j=0;j<=i;j++){
            if(dp[i][j]==0) continue;
            dp[i+1][j+1]+=dp[i][j]*2;
            dp[i+1][j]+=dp[i][j]*8;
        }
    }
}
int slove(int n,int m){
    int bit[20],len=0;
    while(n){
        bit[len++]=n%10;
        n/=10;
    }
    int cnt=0,tot=0;
    for(int i=len-1;i>=0;i--){
        for(int j=0;j<bit[i];j++){
            if(j==4||j==7){
                if(tot!=m) 
                    cnt+=dp[i][m-tot-1];
            }
            else cnt+=dp[i][m-tot];
        }
        if(bit[i]==4||bit[i]==7) tot++;
        if(tot>m) break;
    }
    if(tot==m) cnt++;
    if(m==0) cnt--;
    return cnt;
}
int n;
int cnt[10],t[10];
LL ans=0;
void dfs(int idx,int now,int limit,LL ret){
    if(idx==6){
        ans=(ans+ret)%MOD;
        return ;
    }
    for(int i=0;i<10;i++){
        if(i+now>=limit) break;
        if(t[i]==0) continue;
        t[i]--;
        dfs(idx+1,now+i,limit,ret*(t[i]+1)%MOD);

        t[i]++;
    }
}
int main(){
    DP();
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<10;i++){
            cnt[i]=slove(n,i);
        }
        ans=0;
        for(int i=1;i<10;i++){
            if(cnt[i]==0) continue;
            memcpy(t,cnt,sizeof(cnt));
            t[i]--;
            dfs(0,0,i,cnt[i]%MOD);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

258C:枚举lcm,然后找出所有的因子,假设约数个数为m

第一步先处理,肯定至少有一个数要取lcm,那么至少有一个数取lcm,便是所有>=lcm的数,都有m种可能,这样肯定包括没有取到lcm的情况,只要减掉所有数都取<lcm,即m-1种可能的

然后枚举其它因子

int n;
int a[N],c[N];
LL PowMod(LL a,LL b){
    LL ret=1;
    while(b){
        if(b&1)
            ret=((LL)ret*a)%MOD;
        a=((LL)a*a)%MOD;
        b>>=1;
    }
    return ret;
}
int main(){
    while(scanf("%d",&n)!=EOF){
        int limit=0;
        mem(c,0);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            c[a[i]]++;
            limit=max(limit,a[i]);
        }
        for(int i=N-2;i>=1;i--) 
            c[i]+=c[i+1];
        LL ans=1;
        vector<int>v;
        for(int i=2;i<=limit;i++){
            v.clear();
            for(int j=1;j*j<=i;j++){
                if(i%j==0){
                    v.pb(j);
                    if(j*j!=i)
                        v.pb(i/j);
                }
            }
            sort(v.begin(),v.end());
            int m=v.size();
            LL sum=((PowMod((LL)m,(LL)c[v[m-1]])-PowMod((LL)m-1,(LL)c[v[m-1]]))%MOD+MOD)%MOD;
            for(int j=0;j<m-1;j++){
                sum=(sum*PowMod((LL)j+1,(LL)c[v[j]]-c[v[j+1]]))%MOD;
                if(sum<0) test;
            }
            ans=(ans+sum)%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


258 D:概率DP

p[i][j]表示a[i]>a[j]的概率

那么初始可以得到

对于某一次操作,需要交换a[u],a[v]

那么可以交换,也可能交换,所以p[u][v]=p[v][u]=0.5。因为交换或者不交换,要么是逆序对,要么不是

那么之后枚举所有的i,i!=x&&i!=y

那么以p[u][i]为例,那么a[u]与a[i]的关系,如果a[u]和a[v]不交换,那么p[u][i]不变,这样的可能为p[u][i]*0.5

如果交换的话,则原来的v变为了u,则p[v][i]*0.5

所以p[u][i]=p[u][i]*0.5+p[v][i]*0.5;

最后叠加就是期望



258E:http://blog.csdn.net/acm_cxlove/article/details/8395747


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值