zoukankan      html  css  js  c++  java
  • [考试反思]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,所以就算是模拟赛写高精也是很有必要的。

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

  • 相关阅读:
    Maven 环境的配置
    zTree的简单例子
    plsql免安装客户端的配置
    HDU 1232 畅通工程
    HDU 5698 瞬间移动
    Codeforces 1015E1 Stars Drawing (Easy Edition)
    Codeforces 784B Santa Claus and Keyboard Check
    Codeforces 500C New Year Book Reading
    NSarray 赋值 拷贝 等问题记录
    UINavigationController 操作记录
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11742950.html
Copyright © 2011-2022 走看看