• [考试反思]1026csp-s模拟测试88:发展


    不用你们说,我自己来:我颓闪存我没脸。

    昨天的想法,

    今天的回答。

    生存,

    发展。

    总分榜应该稍有回升,但是和上面的差距肯定还是很大。

    继续。

    为昨天的谬误,承担代价。

    T2和T3都值得张记性。

    T2因为上次输出了"-0.00"在文本比较下与"0.0"不同导致WA,所以这次输出的时候把答案加了0.005

    但是加的太多了,在四舍五入下恰好进位了导致WA。

    为了防止输出"-0.0"要将答案加一个1e-9级别的数,不要太小也不要太大。

    T3算错上限没打高精。

    考虑极端情况。考试时不要用__int128(CSP-S不认可)

    我不喜欢RP守恒。

    我想稳在rank5以内。遥不可及。

    T1:军训队列。

    一个明显的斜率优化dp。但是考场上推了一会没有推出来。

    然而这题用不到,因为身高最多有6001种,所以$O(6001*6001*k)$可过

    但是要注意把所有人身高压起来后n可能小于k,判掉。

    斜率优化的假单调栈可以当成是一个剪枝。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 double dp[100005][21],h[100005];int n,k,q[100005],qh,qt;
     5 double fab2(double x){return x*x;}
     6 double cal(int j,int k,int f){return (dp[j][f-1]-dp[k][f-1])/(h[j+1]-h[k+1])+h[j+1]+h[k+1];}
     7 int main(){
     8     scanf("%d%d",&n,&k);
     9     for(int i=1;i<=n;++i)scanf("%lf",&h[i]);
    10     sort(h+1,h+1+n);n=unique(h+1,h+1+n)-h-1;h[n+1]=1e9;
    11     for(int i=1;i<=n;++i)dp[i][1]=fab2(h[i]-h[1]);
    12     for(int j=2;j<=k;++j){
    13         q[qt=qh=1]=0;
    14         for(int i=1;i<=n;++i){
    15             dp[i][j]=1e18;
    16             while(qt-qh>=1&&cal(q[qh+1],q[qh],j)<h[i]*2)qh++;
    17             for(int p=qh;p<=qt;++p)dp[i][j]=min(dp[i][j],dp[q[p]][j-1]+fab2(h[i]-h[q[p]+1]));
    18             q[++qt]=i;
    19         }
    20     }printf("%.2lf
    ",dp[n][k]);
    21 }
    View Code

    然而当然也可以打一个真正的斜率优化。

    转移式是$dp[i][f]=min(dp[j][f-1]+(h[j+1])^2+(h[i])^2-2 imes h[j+1] imes h[i])$

    然后接下来与i有关的项都可以提出来,剩下的是常数。

    然后就可以得到一个关于$h[i]$的一次函数(直线)。

    因为在这道题里h是单调的,所以斜率是单调的,取值的横坐标也是单调的。

    所以就是一堆直线,可以维护凸包了。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 double dp[100005][21],h[100005],k[100005],b[100005];int n,K,q[100005],qh,qt;
     5 double fab2(double x){return x*x;}
     6 double cal(int j,double x){return b[j]+k[j]*x;}
     7 double jd(int j,int i){return (b[j]-b[i])/(k[i]-k[j]);}
     8 int main(){
     9     scanf("%d%d",&n,&K);
    10     for(int i=1;i<=n;++i)scanf("%lf",&h[i]);
    11     sort(h+1,h+1+n);n=unique(h+1,h+1+n)-h-1;h[n+1]=1e9;
    12     for(int i=1;i<=n;++i)dp[i][1]=fab2(h[i]-h[1]);
    13     for(int j=2;j<=K;++j){
    14         q[qt=qh=1]=j-1;k[j-1]=-2*h[j];b[j-1]=dp[j-1][j-1]+fab2(h[j]);
    15         for(int i=j;i<=n;++i){
    16             k[i]=-2*h[i+1];b[i]=dp[i][j-1]+fab2(h[i+1]);
    17             while(qt-qh>=1&&cal(q[qh],h[i])>cal(q[qh+1],h[i]))qh++;
    18             while(qt-qh>=1&&jd(q[qt-1],i)>jd(q[qt],i))qt--;
    19             dp[i][j]=dp[q[qh]][j-1]+fab2(h[i]-h[q[qh]+1]);
    20             q[++qt]=i;
    21         }
    22     }printf("%.2lf
    ",dp[n][K]);
    23 }
    View Code

    T2:山屋惊魂

    规模不是很大的模拟。虽说也不小。

    预处理一下dize[i][j]表示用i个骰子得到j的概率。(骰子的英语不是dize。。。打脸。。。但是我懒得改了)

    然后。。我也不知道该讲什么。。。模拟好像真的没办法讲。。。

    按照题目说的就是了。不要读错题

    其实我不是很明白为什么会打的那么长,并没有感觉这个模拟比以前的模拟难很多。。。

     1 #include<cstdio>
     2 #include<string>
     3 #include<iostream>
     4 #include<map>
     5 using namespace std;
     6 map<string,int>M;
     7 long double dize[9][17],pos[101][4098],fail,ans[4][8],lim[102][4][8];
     8 int n,st[4],s[102],c1[102],c2[102],num;
     9 string bar[4],knd,opt;
    10 int chg(int S,int p,int w){return (S^S&7<<p*3)|w<<p*3;}
    11 int main(){//freopen("betrayal.in","r",stdin);
    12     dize[0][0]=1;
    13     for(int i=0;i<=7;++i)for(int j=0;j<=i<<1;++j)
    14         dize[i+1][j]+=dize[i][j]/3,dize[i+1][j+1]+=dize[i][j]/3,dize[i+1][j+2]+=dize[i][j]/3;
    15     for(int i=0;i<4;++i)cin>>bar[i]>>st[i],st[i]--;
    16     cin>>n;
    17     pos[0][st[0]|st[1]<<3|st[2]<<6|st[3]<<9]=1;
    18     M["Might"]=0;M["Speed"]=1;M["Sanity"]=2;M["Knowledge"]=3;
    19     for(int i=0;i<n;++i){
    20         cin>>knd>>opt;
    21         if(opt=="<"){
    22             cin>>num;
    23             for(int j=0;j<=7;++j)for(int k=0;k<=16;++k)lim[i][M[knd]][j]+=(dize[bar[M[knd]][j]-'0'][k]*(k>=num));
    24             cin>>knd>>opt;
    25         }else if(opt=="<="){
    26             cin>>num;
    27             for(int j=0;j<=7;++j)for(int k=0;k<=16;++k)lim[i][M[knd]][j]+=(dize[bar[M[knd]][j]-'0'][k]*(k> num));
    28             cin>>knd>>opt;
    29         }else if(opt==">"){
    30             cin>>num;
    31             for(int j=0;j<=7;++j)for(int k=0;k<=16;++k)lim[i][M[knd]][j]+=(dize[bar[M[knd]][j]-'0'][k]*(k<=num));
    32             cin>>knd>>opt;
    33         }else if(opt==">="){
    34             cin>>num;
    35             for(int j=0;j<=7;++j)for(int k=0;k<=16;++k)lim[i][M[knd]][j]+=(dize[bar[M[knd]][j]-'0'][k]*(k< num));
    36             cin>>knd>>opt;
    37         }
    38         s[i]=M[knd];
    39         if(opt[0]=='+')if(opt.length()==3)c2[i]+=opt[1]-'0';
    40             else c1[i]+=opt[1]-'0';
    41         if(opt[0]=='-')if(opt.length()==3)c2[i]-=opt[1]-'0';
    42             else c1[i]-=opt[1]-'0';//printf("%d %d %d
    ",s[i],c1[i],c2[i]);
    43     }
    44     for(int i=0;i<n;++i)for(int S=0;S<1<<12;++S){
    45         int state[4]={S&7,S>>3&7,S>>6&7,S>>9&7};
    46         double rp=pos[i][S];
    47         for(int j=0;j<4;++j)rp*=(1-lim[i][j][state[j]]);
    48         pos[i+1][S]+=pos[i][S]-rp;
    49         if(c1[i]){
    50             state[s[i]]+=c1[i];state[s[i]]=min(state[s[i]],7);
    51             if(state[s[i]]<0)fail+=rp;
    52             else pos[i+1][chg(S,s[i],state[s[i]])]+=rp;
    53         }else if(c2[i]>=0){
    54             for(int r=0;r<=16;++r){
    55                 double P=rp*dize[c2[i]][r];
    56                 int nw=state[s[i]]+r;nw=min(nw,7);
    57                 pos[i+1][chg(S,s[i],nw)]+=P;
    58             }
    59         }else{
    60             for(int r=0;r<=16;++r){
    61                 double P=rp*dize[-c2[i]][r];
    62                 int nw=state[s[i]]-r;
    63                 if(nw<0)fail+=P;
    64                 else pos[i+1][chg(S,s[i],nw)]+=P;
    65             }
    66         }ed:;
    67     }
    68     printf("%.2Lf
    ",fail*100+0.0001);
    69     for(int i=0;i<1<<12;++i)for(int k=0;k<4;++k)ans[k][bar[k][i>>k*3&7]-'1']+=pos[n][i];
    70     for(int k=0;k<4;++k,puts(""))for(int i=0;i<8;++i)printf("%.2Lf ",ans[k][i]*100+0.0001);
    71 }
    2.4k,可写
     1 #include<cstdio>
     2 #include<string>
     3 #include<iostream>
     4 #include<map>
     5 using namespace std;
     6 map<string,int>M;
     7 double dize[9][17],pos[101][4098],fail,ans[4][8],lim[102][4][8];
     8 int n,st[4],s[102],c1[102],c2[102],num;
     9 string bar[4],knd,opt;
    10 int chg(int S,int p,int w){return (S^S&7<<p*3)|w<<p*3;}
    11 int abs(int a){return a>0?a:-a;}
    12 int nt(int a){return a>0?1:-1;}
    13 int OPT(string s,int a,int b){return s=="<="?a>b:(s=="<"?a>=b:(s==">="?a<b:a<=b));}
    14 int main(){
    15     dize[0][0]=1;
    16     for(int i=0;i<8;++i)for(int j=0;j<=i*2;++j)
    17         dize[i+1][j]+=dize[i][j]/3,dize[i+1][j+1]+=dize[i][j]/3,dize[i+1][j+2]+=dize[i][j]/3;
    18     for(int i=0;i<4;++i)cin>>bar[i]>>st[i],st[i]--;
    19     cin>>n; pos[0][st[0]|st[1]<<3|st[2]<<6|st[3]<<9]=1;
    20     M["Speed"]=1;M["Sanity"]=2;M["Knowledge"]=3;
    21     for(int i=0;i<n;++i){
    22         cin>>knd>>opt;
    23         if(opt[0]!='+'&&opt[0]!='-'){
    24             cin>>num;
    25             for(int j=0;j<8;++j)for(int k=0;k<=16;++k)
    26                 lim[i][M[knd]][j]+=(dize[bar[M[knd]][j]-'0'][k]*OPT(opt,k,num));
    27             cin>>knd>>opt;
    28         }
    29         s[i]=M[knd];
    30         if(opt.length()==3)c2[i]+=(opt[1]-'0')*(opt[0]=='+'?1:-1);
    31         else c1[i]+=(opt[1]-'0')*(opt[0]=='+'?1:-1);
    32     }
    33     for(int i=0;i<n;++i)for(int S=0;S<1<<12;++S){
    34         int state[4]={S&7,S>>3&7,S>>6&7,S>>9&7}; double rp=pos[i][S];
    35         for(int j=0;j<4;++j)rp*=(1-lim[i][j][state[j]]);
    36         pos[i+1][S]+=pos[i][S]-rp;
    37         if(c1[i]){
    38             state[s[i]]+=c1[i];state[s[i]]=min(state[s[i]],7);
    39             if(state[s[i]]<0)fail+=rp;
    40             else pos[i+1][chg(S,s[i],state[s[i]])]+=rp;
    41         }else for(int r=0;r<=16;++r){
    42             double P=rp*dize[abs(c2[i])][r];
    43             int nw=state[s[i]]+nt(c2[i])*r;nw=min(nw,7);
    44             if(nw<0)fail+=P;else pos[i+1][chg(S,s[i],nw)]+=P;
    45         }
    46     }
    47     printf("%.2lf
    ",fail*100+1e-6);
    48     for(int i=0;i<1<<12;++i)for(int k=0;k<4;++k)ans[k][bar[k][i>>k*3&7]-'1']+=pos[n][i];
    49     for(int k=0;k<4;++k,puts(""))for(int i=0;i<8;++i)printf("%.2lf ",ans[k][i]*100+1e-6);
    50 }
    1.8k,压行

    压行后的代码不存在任何的复制粘贴了,可以简单扩展了。

    T3:彩球问题

    记忆化搜索/dp

    状态4维,12/12/12/4,分别表示还有1/2/3个的球有几种颜色,且上一次用的球还剩下0/1/2个

    然后又是模拟?

    最后的答案貌似有$10^{33}$级别?

     1 #include<cstdio>
     2 #define dp re[c1][c2][c3][lst]
     3 __int128 ans,re[13][13][13][3];int cnt[4],n,x;
     4 __int128 sch(int c1,int c2,int c3,int lst){
     5     if(dp!=-1)return dp;
     6     dp=0;
     7     if(c1==0&&c2==0&&c3==0)return 1;
     8     if(lst==0){
     9         if(c1)dp+=c1*sch(c1-1,c2,c3,0);
    10         if(c2)dp+=c2*sch(c1+1,c2-1,c3,1);
    11         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    12     }else if(lst==1){
    13         if(c1>1)dp+=(c1-1)*sch(c1-1,c2,c3,0);
    14         if(c2)dp+=c2*sch(c1+1,c2-1,c3,1);
    15         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    16     }else if(lst==2){
    17         if(c1)dp+=c1*sch(c1-1,c2,c3,0);
    18         if(c2>1)dp+=(c2-1)*sch(c1+1,c2-1,c3,1);
    19         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    20     }return dp;
    21 }
    22 int main(){
    23     scanf("%d",&n);
    24     while(n--)scanf("%d",&x),cnt[x]++;
    25     for(int i=0;i<13;++i)for(int j=0;j<13;++j)for(int k=0;k<13;++k)for(int l=0;l<3;++l)re[i][j][k][l]=-1;
    26     __int128 x=sch(cnt[1],cnt[2],cnt[3],0);
    27     if(x/1000000000000000000ll)printf("%lld",(long long)(x/1000000000000000000ll));
    28     printf("%lld
    ",(long long)(x%1000000000000000000ll));
    29 }
    你可以用int128水过
     1 #include<cstdio>
     2 #define dp re[c1][c2][c3][lst]
     3 struct LL{
     4     long long x[5];
     5     #define mod 100000000
     6     friend void operator+=(LL &a,LL b){
     7         for(int i=0;i<5;++i)a.x[i]+=b.x[i];
     8         for(int i=0;i<4;++i)a.x[i+1]+=a.x[i]/mod,a.x[i]%=mod;
     9     }
    10     void print(int i=4){
    11         for(;~i;--i)if(x[i]){printf("%lld",x[i]);break;}
    12         for(--i;~i;--i)printf("%08lld",x[i]);
    13     }
    14     friend LL operator*(int x,LL a){
    15         for(int i=0;i<5;++i)a.x[i]*=x;
    16         for(int i=0;i<4;++i)a.x[i+1]+=a.x[i]/mod,a.x[i]%=mod;
    17         return a;
    18     }
    19     friend bool operator!=(LL a,int x){return a.x[0]!=-1;}
    20     void operator=(int p){x[0]=p;}
    21 };
    22 LL ans,re[13][13][13][3];int cnt[4],n,x;
    23 LL sch(int c1,int c2,int c3,int lst){
    24     if(dp!=-1)return dp;
    25     dp=0;
    26     if(c1==0&&c2==0&&c3==0)return dp=1,dp;
    27     if(lst==0){
    28         if(c1)dp+=c1*sch(c1-1,c2,c3,0);
    29         if(c2)dp+=c2*sch(c1+1,c2-1,c3,1);
    30         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    31     }else if(lst==1){
    32         if(c1>1)dp+=(c1-1)*sch(c1-1,c2,c3,0);
    33         if(c2)dp+=c2*sch(c1+1,c2-1,c3,1);
    34         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    35     }else if(lst==2){
    36         if(c1)dp+=c1*sch(c1-1,c2,c3,0);
    37         if(c2>1)dp+=(c2-1)*sch(c1+1,c2-1,c3,1);
    38         if(c3)dp+=c3*sch(c1,c2+1,c3-1,2);
    39     }return dp;
    40 }
    41 int main(){
    42     scanf("%d",&n);
    43     while(n--)scanf("%d",&x),cnt[x]++;
    44     for(int i=0;i<13;++i)for(int j=0;j<13;++j)for(int k=0;k<13;++k)for(int l=0;l<3;++l)re[i][j][k][l]=-1;
    45     sch(cnt[1],cnt[2],cnt[3],0).print();
    46 }
    但是显然作为一个有脸的人还是要写一次高精的

    因为真正CSP-S上也不能用__int128,所以就算是模拟赛写高精也是很有必要的。

    态度必须要有,天人不相欺。

  • 相关阅读:
    Typescript 最佳实践
    《三》大话 Typescript 接口
    二. 细说小程序登陆
    一. 优化小程序自身的Storage
    开始你的第一个npm脚本工具
    javascript 玩转Date对象
    createjs 小游戏开发实战
    前端实现连连看小游戏(1)
    一篇文章带你快速入门createjs
    从0到1完成小程序开发(4)
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11742950.html
Copyright © 2020-2023  润新知