2017-10-16离线赛

大体状况

172/300
状态十分差劲= =

T1 multiple

分析

二分然后计算数量然后求一个最大值。
理论复杂度为 O(Tmlog221018)
然后那个评测机果然没有跑过去,
只有62分
3分是1计算为0导致的
(在网站上都能过啊

代码
#include<bits/stdc++.h>
using namespace std;

#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
#define LL long long

void Rd(int &res){
    char c;res=0;
    while((c=getchar())<48);
    do res=(res<<3)+(res<<1)+(c^48);
    while((c=getchar())>47);
}
void Rd(LL &res){
    char c;res=0;
    while((c=getchar())<48);
    do res=(res<<3)+(res<<1)+(c^48);
    while((c=getchar())>47);
}
#define M 104
int Pri[M]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541};
int T,m;
LL A[M],Ans;
LL Num[M][M];
void Init(){
    REP(i,0,100){
        LL v=1;
        Num[i][0]=1;
        REP(j,1,74)
            v*=Pri[i],Num[i][j]=Num[i][j-1]+v;
    }
}
LL Calc(int i,int p,LL x){
    LL Res=0;int len=0;x/=p;
    while(x) Res+=x%p*Num[i][len++],x/=p;
    return Res;
}
void Solve(){
    Ans=1;
    DREP(i,m-1,-1){
        if(Calc(i,Pri[i],Ans)>=A[i])continue;
        LL l=Ans,r=1000000000000000000ll,Res=0;
        while(l<=r){
            LL Mid=l+r>>1;
            if(Calc(i,Pri[i],Mid)>=A[i])r=Mid-1,Res=Mid;
            else l=Mid+1;
        }
        chkmax(Ans,Res);
    }
    printf("%lld\n",Ans);
}
int main(){
    Init();
    Rd(T);
    while(T--){
        Rd(m);
        REP(i,0,m)Rd(A[i]);
        Solve();
    }
    return 0;
}

T2 bracket

分析
P60

朴素的DP。

P100

贪心。
令所有字符视为?,把其转换为另一个括号的代价设为INF。
累计所有转换为右括号的代价和,
然后令转换为左括号的代价减去其转换为右括号的代价和。
这样就变成求合法的n/2个左括号的代价和最小。
然后弄一个优先队列,发现在奇数位取值是肯定可以合法的。

代码

这样并没有把已有的左右括号特殊处理的方法跑得快。
当然复杂度是一样的。

#include<bits/stdc++.h>
using namespace std;

#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define LL long long

void Rd(int &res){
    char c;res=0;
    while((c=getchar())<48);
    do res=(res<<3)+(res<<1)+(c^48);
    while((c=getchar())>47);
}

#define M 200004
#define INF 2000000044
char C[M];
int n,X[M],Y[M];
LL Ans;
priority_queue<int>Q;
int main(){
    scanf("%s",C);
    n=strlen(C);

    REP(i,0,n){
        if(C[i]=='?')Rd(X[i]),Rd(Y[i]);
        else if(C[i]==')')X[i]=INF;
        else Y[i]=INF;
        Ans+=Y[i],X[i]-=Y[i];
    }

    REP(i,0,n){
        Q.push(-X[i]);
        if(!(i&1)) Ans-=Q.top(),Q.pop();
    }

    printf("%lld\n",Ans);
    return 0;
}

T3 trennen

P50(?80)

贪心的这个策略比较显然。
必然从右侧开始按开关,
右侧的灯只有自己这个开关与更右侧是其倍数的开关能改变其状态。
如果按更右侧的开关来关这盏灯,最后还要按一次那个更右侧的开关。
而该开关的约数真包含于更右侧的开关的约数,
因此按那个开关没有意义。
也即,确定了序列后开关的次数必然小于等于n,
可以用上述策略得到最小次数。
对于 k==n 的情况,就可以直接输出这个步数乘上n!。
实际上给了80分。

P100

通过上面那个策略以及这个游戏的本质可以发现:
操作顺序对操作结果没有影响。
所以当在需要操作 t 次的情况中,一定有tn的概率使其减少一次操作以及 ntn 的概率使其增加一次操作。
然后这就是一个简单的概率DP了。
定义 Fi 为状态 i 到状态i1所需的期望步数。
Fn=1
Fi=tn+ntn(Fi+Fi+1+1)
后一项为先转化为状态 i+1 然后通过F变回来= =。
整理可得 Fi=n+(ni)Fi+1i
然后就可以递推了,答案为 nowi=k+1
now为初始状态所需步数。
整个题目就是这个叫B君的zz不会贪心去随机的结果= =

代码
#include<bits/stdc++.h>
using namespace std;

#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
#define LL long long

void Rd(int &res){
    char c;res=0;
    while((c=getchar())<48);
    do res=(res<<3)+(res<<1)+(c^48);
    while((c=getchar())>47);
}
#define M 100004
#define Mod 100003
int n,k,A[M];
int Solve(){
    int Ans=0;
    DREP(i,n,0){
        for(int j=i+i;j<=n;j+=i)if(A[j])A[i]^=1;
        Ans+=A[i];
    }
    return Ans;
}
int Pow(int x,int p){
    int Res=1,k=x;
    while(p){
        if(p&1)Res=1ll*Res*k%Mod;
        k=1ll*k*k%Mod;p>>=1;
    }
    return Res;
}
int Fac(int x){
    REP(i,2,n+1)
        x=1ll*x*i%Mod;
    return x;
}
int main(){
    Rd(n),Rd(k);
    REP(i,1,n+1)Rd(A[i]);
    int Tmp=Solve();
    if(Tmp<=k)printf("%d\n",Fac(Tmp));
    else{
        int Res=1,Ans=0;
        DREP(i,n-1,k){
            Res=1ll*(n+1ll*Res*(n-i)%Mod)*Pow(i,Mod-2)%Mod;
            if(i<=Tmp)(Ans+=Res)%=Mod;
        }
        Ans+=k;
        printf("%d\n",Fac(Ans));
    }
    return 0;
}

总结

概率DP还是并不怎么会,一看见期望值就懵逼。
这种DP的一个明显特征就是以普通状态转移之间的差值作为DP值。
将二维需要高斯消元的状态关系化为一维比较麻烦。
然后T2的贪心,应该算比较明显了但是没有想到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值