• csps模拟87888990部分题解


    题面:https://www.cnblogs.com/Juve/articles/11752338.html https://www.cnblogs.com/Juve/articles/11752414.html

    最近咕的稍多,就简单写一下题解了(其实也不算题解),反正就是一句话,而且都是这几套题改完的

    模拟87:

    maze

    在实数上二分,跑最短路check,spfa比dij快多l

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cmath>
      7 #define int long long
      8 using namespace std;
      9 const int MAXN=105;
     10 int n,m,sx,sy,tx,ty;
     11 int dx[4]={0,0,1,-1};
     12 int dy[4]={1,-1,0,0};
     13 bool mp[MAXN][MAXN],vis[MAXN*MAXN];
     14 double s,dis[MAXN*MAXN],l,r,ans;
     15 int calc(int x,int y){
     16     return (x-1)*m+y;
     17 }
     18 queue< pair<int,int> >qu;
     19 double spfa(int x,int y,double k){
     20     for(int i=1;i<=n;++i)
     21         for(int j=1;j<=m;++j) dis[calc(i,j)]=1e11;
     22     //printf("%0.0lf
    ",dis[1]);
     23     memset(vis,0,sizeof(vis));
     24     int st=calc(x,y);
     25     dis[st]=0.0;
     26     qu.push(make_pair(x,y));
     27     vis[st]=1;
     28     while(!qu.empty()){
     29         pair<int,int>p=qu.front();
     30         qu.pop();
     31         int xx=p.first,yy=p.second;
     32         st=calc(xx,yy);
     33         for(int i=0;i<4;++i){
     34             int a=xx+dx[i],b=yy+dy[i];
     35             if(mp[a][b]==1||a<1||b<1||a>n||b>m) continue;
     36             int c=calc(a,b);
     37             if(i<2){
     38                 if(dis[c]>dis[st]+1.0){
     39                     dis[c]=dis[st]+1.0;
     40                     if(!vis[c]) qu.push(make_pair(a,b));
     41                 }
     42             }else{
     43                 if(dis[c]>dis[st]+k){
     44                     dis[c]=dis[st]+k;
     45                     if(!vis[c]) qu.push(make_pair(a,b));
     46                 }
     47             }
     48         }
     49         vis[st]=0;
     50     }
     51     return dis[calc(tx,ty)];
     52 }
     53 priority_queue< pair<double, pair<int,int> > > q;
     54 double dijkstra(int x,int y,double k){
     55     for(int i=1;i<=n;++i)
     56         for(int j=1;j<=m;++j) dis[calc(i,j)]=1e11;
     57     //printf("%0.0lf
    ",dis[1]);
     58     memset(vis,0,sizeof(vis));
     59     int st=calc(x,y);
     60     dis[st]=0.0;
     61     q.push(make_pair(0.0,make_pair(x,y)));
     62     while(!q.empty()){
     63         pair<int,int>p=q.top().second;
     64         q.pop();
     65         int xx=p.first,yy=p.second;
     66         st=calc(xx,yy);
     67         if(vis[st]) continue;
     68         vis[st]=1;
     69         for(int i=0;i<4;++i){
     70             int a=xx+dx[i],b=yy+dy[i];
     71             if(mp[a][b]==1||a<1||b<1||a>n||b>m) continue;
     72             int c=calc(a,b);
     73             if(i<2){
     74                 if(dis[c]>dis[st]+1.0){
     75                     dis[c]=dis[st]+1.0;
     76                     q.push(make_pair(-dis[c],make_pair(a,b)));
     77                 }
     78             }else{
     79                 if(dis[c]>dis[st]+k){
     80                     dis[c]=dis[st]+k;
     81                     q.push(make_pair(-dis[c],make_pair(a,b)));
     82                 }
     83             }
     84         }
     85     }
     86     //cout<<calc(tx,ty)<<' '<<dis[calc(tx,ty)]<<endl;
     87     return dis[calc(tx,ty)];
     88 }
     89 signed main(){
     90     //freopen("test.in","r",stdin);
     91     scanf("%lld%lld",&n,&m);
     92     scanf("%lld%lld%lld%lld",&sx,&sy,&tx,&ty);
     93     for(int i=1;i<=n;++i){
     94         for(int j=1,x;j<=m;++j){
     95             scanf("%lld",&x);
     96             mp[i][j]=x;
     97         }
     98     }
     99     scanf("%lf",&s);
    100     l=0,r=s;
    101     while(fabs(r-l)>1e-5){
    102         double mid=(r+l)/2.0;
    103         if(dijkstra(sx,sy,mid)<=s) ans=mid,l=mid;
    104         else r=mid;
    105     }
    106     printf("%0.3lf
    ",ans);
    107     return 0;
    108 }
    View Code

    bird:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 using namespace std;
     7 const int MAXN=5e5+5;
     8 int n,k,tot=0,f[MAXN],maxx=0,ans=0;
     9 struct node{
    10     int l,r;
    11     friend bool operator < (node p,node q){
    12         return p.r==q.r?p.l<q.l:p.r<q.r;
    13     }
    14 }b[MAXN];
    15 int c[MAXN],num[MAXN],d[MAXN],in[MAXN];
    16 int max(int a,int b){
    17     return a>b?a:b;
    18 }
    19 int tr[MAXN<<2],laz[MAXN<<2];
    20 void down(int k){
    21     tr[k<<1]+=laz[k],tr[k<<1|1]+=laz[k];
    22     laz[k<<1]+=laz[k],laz[k<<1|1]+=laz[k];
    23     laz[k]=0;
    24 }
    25 void update(int k,int l,int r,int pos,int val){
    26     if(l==r){
    27         tr[k]=val;
    28         return ;
    29     }
    30     if(laz[k]) down(k);
    31     int mid=(l+r)>>1;
    32     if(pos<=mid) update(k<<1,l,mid,pos,val);
    33     else update(k<<1|1,mid+1,r,pos,val);
    34     tr[k]=max(tr[k<<1],tr[k<<1|1]);
    35 }
    36 void update(int k,int l,int r,int opl,int opr,int val){
    37     if(opl<=l&&r<=opr){
    38         tr[k]+=val,laz[k]+=val;
    39         return ;
    40     }
    41     if(laz[k]) down(k);
    42     int mid=(l+r)>>1;
    43     if(opl<=mid) update(k<<1,l,mid,opl,opr,val);
    44     if(opr>mid) update(k<<1|1,mid+1,r,opl,opr,val);
    45     tr[k]=max(tr[k<<1],tr[k<<1|1]);
    46 }
    47 int query(int k,int l,int r,int opl,int opr){
    48     if(opl<=l&&r<=opr) return tr[k];
    49     if(laz[k]) down(k);
    50     int mid=(l+r)>>1,res=0;
    51     if(opl<=mid) res=max(res,query(k<<1,l,mid,opl,opr));
    52     if(opr>mid) res=max(res,query(k<<1|1,mid+1,r,opl,opr));
    53     return res;
    54 }
    55 signed main(){
    56     scanf("%lld%lld",&n,&k);
    57     for(int i=1,l,r;i<=n;++i){
    58         scanf("%lld%lld",&l,&r);
    59         if(r<0) continue;
    60         l=max(0,l);++l,++r;
    61         b[++tot]=(node){l,r};
    62         ++d[l],--d[r+1],++in[l];
    63         maxx=max(maxx,r+1);
    64     }
    65     sort(b+1,b+tot+1);
    66     for(int i=1;i<=maxx;++i) d[i]+=d[i-1];
    67     int now=0,p=1;
    68     for(int i=1;i<=maxx;++i){
    69         f[i]=d[i]+query(1,0,maxx,max(0,i-2*k),max(0,i-k));
    70         ans=max(f[i],ans);
    71         now+=in[i];
    72         update(1,0,maxx,i,f[i]-now);
    73         while(p<=tot&&b[p].r==i){
    74             --now;
    75             update(1,0,maxx,b[p].l,b[p].r,1);
    76             ++p;
    77         }
    78     }
    79     printf("%lld
    ",ans);
    80     return 0;
    81 }
    View Code

    stone:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 using namespace std;
     7 const int MAXN=1e6+5;
     8 int n,m,ans=0,l[MAXN],r[MAXN],sum[3][3][MAXN];
     9 char s1[MAXN],s2[MAXN];
    10 signed main(){
    11     scanf("%s%s",s1+1,s2+1);
    12     n=strlen(s1+1),m=strlen(s2+1);
    13     int p=1;
    14     for(int i=1;i<=n;++i){
    15         l[i]=p;
    16         if(s1[i]==s2[p]) ++p;
    17     }
    18     p=1;
    19     for(int i=1;i<=m;++i){
    20         if(s2[i]==s1[p]) ++p;
    21         r[p]=min(i+1,m);
    22     }
    23     if(r[1]==0) r[1]=1;
    24     for(int i=1;i<=n;++i){
    25         if(!r[i]) r[i]=m;
    26         ans+=r[i]-l[i]+1;
    27     }
    28     for(int i=2;i<=m;++i){
    29         for(int k1=0;k1<3;++k1)
    30             for(int k2=0;k2<3;++k2){
    31                 sum[k1][k2][i]=sum[k1][k2][i-1];
    32             }
    33         ++sum[s2[i]-'A'][s2[i-1]-'A'][i];
    34     }
    35     for(int i=2;i<=n;++i){
    36         if(s1[i-1]!=s1[i])
    37             ans-=sum[s1[i-1]-'A'][s1[i]-'A'][r[i]]-sum[s1[i-1]-'A'][s1[i]-'A'][l[i]-1];
    38         //cout<<i<<' '<<ans<<' '<<s1[i-1]-'A'<<' '<<s1[i]-'A'<<endl;
    39     }
    40     printf("%lld
    ",ans);
    41     return 0;
    42 }
    View Code

    模拟88:

    军训队列:

    排序一定不会更劣,

    设f[i][j]表示前i个分了j个队列的最小值,则有方程:$f[i][j]=min(f[p][j-1]+(a[i]-a[p])^2),pin[1,i]$

    然后我们发现值域很小,unique后就能过了,当然也可以斜率优化

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 using namespace std;
     7 const int MAXN=1e5+5;
     8 int n,k;
     9 double a[MAXN],f[MAXN][25],ans;
    10 signed main(){
    11     scanf("%lld%lld",&n,&k);
    12     memset(f,127,sizeof(f));
    13     for(int i=1;i<=n;++i){
    14         scanf("%lf",&a[i]);
    15     }
    16     f[0][0]=0;
    17     sort(a+1,a+n+1);
    18     n=unique(a+1,a+n+1)-a-1;
    19     for(int i=1;i<=n;++i){
    20         for(int j=1;j<=min(i,k);++j)
    21             for(int p=1;p<=i;++p){
    22                 f[i][j]=min(f[i][j],f[p-1][j-1]+(a[i]-a[p])*(a[i]-a[p]));
    23             }
    24     }
    25     printf("%0.2lf
    ",f[n][min(n,k)]);
    26     return 0;
    27 }
    View Code

    山屋惊魂:模拟+概率

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 double res[10][20],f[102][10][10][10][10],ans[4][9],dead;
      7 char ch[12];
      8 int p[4],ww[4][9],n;
      9 int cal(){
     10     if(ch[1]=='M') return 0;
     11     else if(ch[2]=='p') return 1;
     12     else if(ch[2]=='a') return 2;
     13     else return 3;
     14 }
     15 int calc(){
     16     int len=strlen(ch+1);
     17     if(len==2){
     18         if(ch[1]=='>') return 4;
     19         else return 2;
     20     }else{
     21         if(ch[1]=='<') return 1;
     22         else return 3;
     23     }
     24 }
     25 void work1(int tim,int pos,int val){
     26     for(int i=1;i<=8;++i){
     27         for(int j=1;j<=8;++j){
     28             for(int p=1;p<=8;++p){
     29                 for(int q=1,now;q<=8;++q){
     30                     if(pos==0){
     31                         if(i+val<=0) continue;
     32                         now=min(8,i+val);
     33                         f[tim][now][j][p][q]+=f[tim-1][i][j][p][q];
     34                     }else if(pos==1){
     35                         if(j+val<=0) continue;
     36                         int now=min(8,j+val);
     37                         f[tim][i][now][p][q]+=f[tim-1][i][j][p][q];
     38                     }else if(pos==2){
     39                         if(p+val<=0) continue;
     40                         now=min(8,p+val);
     41                         f[tim][i][j][now][q]+=f[tim-1][i][j][p][q];
     42                     }else{
     43                         if(q+val<=0) continue;
     44                         now=min(8,q+val);
     45                         f[tim][i][j][p][now]+=f[tim-1][i][j][p][q];
     46                     }
     47                 }
     48             }
     49         }
     50     }
     51 }
     52 void work2(int tim,int pos,int flag,int val){
     53     for(int i=1;i<=8;++i){
     54         for(int j=1;j<=8;++j){
     55             for(int p=1;p<=8;++p){
     56                 for(int q=1,now;q<=8;++q){
     57                     for(int k=0;k<=2*val;++k){
     58                         if(pos==0){
     59                             if(i+flag*k<=0) continue;
     60                             now=min(8,i+flag*k);
     61                             f[tim][now][j][p][q]+=f[tim-1][i][j][p][q]*res[val][k];
     62                         }else if(pos==1){
     63                             if(j+flag*k<=0) continue;
     64                             int now=min(8,j+flag*k);
     65                             f[tim][i][now][p][q]+=f[tim-1][i][j][p][q]*res[val][k];
     66                         }else if(pos==2){
     67                             if(p+flag*k<=0) continue;
     68                             now=min(8,p+flag*k);
     69                             f[tim][i][j][now][q]+=f[tim-1][i][j][p][q]*res[val][k];
     70                         }else{
     71                             if(q+flag*k<=0) continue;
     72                             now=min(8,q+flag*k);
     73                             f[tim][i][j][p][now]+=f[tim-1][i][j][p][q]*res[val][k];
     74                         }
     75                     }
     76                 }
     77             }
     78         }
     79     }
     80 }
     81 void work3(int tim,int pos1,int fh,int lim,int pos2,int flag,int val){//第几次,用pos1判定,符号,判定的数,给谁改变,加还是减,加或减多少
     82     val*=flag;
     83     for(int i=1;i<=8;++i){
     84         for(int j=1;j<=8;++j){
     85             for(int p=1;p<=8;++p){
     86                 for(int q=1;q<=8;++q){
     87                     double ban=0.0;
     88                     for(int k=0;k<=16;++k){
     89                         if(fh==1){//<
     90                             if(pos1==0) ban+=(k<lim)*res[ww[0][i]][k];
     91                             else if(pos1==1) ban+=(k<lim)*res[ww[1][j]][k];
     92                             else if(pos1==2) ban+=(k<lim)*res[ww[2][p]][k];
     93                             else ban+=(k<lim)*res[ww[3][q]][k];
     94                         }else if(fh==2){//<=
     95                             if(pos1==0) ban+=(k<=lim)*res[ww[0][i]][k];
     96                             else if(pos1==1) ban+=(k<=lim)*res[ww[1][j]][k];
     97                             else if(pos1==2) ban+=(k<=lim)*res[ww[2][p]][k];
     98                             else ban+=(k<=lim)*res[ww[3][q]][k];
     99                         }else if(fh==3){//>
    100                             if(pos1==0) ban+=(k>lim)*res[ww[0][i]][k];
    101                             else if(pos1==1) ban+=(k>lim)*res[ww[1][j]][k];
    102                             else if(pos1==2) ban+=(k>lim)*res[ww[2][p]][k];
    103                             else ban+=(k>lim)*res[ww[3][q]][k];
    104                         }else{//>=
    105                             if(pos1==0) ban+=(k>=lim)*res[ww[0][i]][k];
    106                             else if(pos1==1) ban+=(k>=lim)*res[ww[1][j]][k];
    107                             else if(pos1==2) ban+=(k>=lim)*res[ww[2][p]][k];
    108                             else ban+=(k>=lim)*res[ww[3][q]][k];
    109                         }
    110                     }
    111                     f[tim][i][j][p][q]+=(1.0-ban)*f[tim-1][i][j][p][q];
    112                     int now;
    113                     if(pos2==0){
    114                         if(i+val<=0) continue;
    115                         now=min(8,i+val);
    116                         f[tim][now][j][p][q]+=ban*f[tim-1][i][j][p][q];
    117                     }else if(pos2==1){
    118                         if(j+val<=0) continue;
    119                         int now=min(8,j+val);
    120                         f[tim][i][now][p][q]+=ban*f[tim-1][i][j][p][q];
    121                     }else if(pos2==2){
    122                         if(p+val<=0) continue;
    123                         now=min(8,p+val);
    124                         f[tim][i][j][now][q]+=ban*f[tim-1][i][j][p][q];
    125                     }else{
    126                         if(q+val<=0) continue;
    127                         now=min(8,q+val);
    128                         f[tim][i][j][p][now]+=ban*f[tim-1][i][j][p][q];
    129                     }
    130                 }
    131             }
    132         }
    133     }
    134 }
    135 void work4(int tim,int pos1,int fh,int lim,int pos2,int flag,int val){
    136     for(int i=1;i<=8;++i){
    137         for(int j=1;j<=8;++j){
    138             for(int p=1;p<=8;++p){
    139                 for(int q=1;q<=8;++q){
    140                     double ban=0.0;
    141                     for(int k=0;k<=16;++k){
    142                         if(fh==1){//<
    143                             if(pos1==0) ban+=(k<lim)*res[ww[0][i]][k];
    144                             else if(pos1==1) ban+=(k<lim)*res[ww[1][j]][k];
    145                             else if(pos1==2) ban+=(k<lim)*res[ww[2][p]][k];
    146                             else ban+=(k<lim)*res[ww[3][q]][k];
    147                         }else if(fh==2){//<=
    148                             if(pos1==0) ban+=(k<=lim)*res[ww[0][i]][k];
    149                             else if(pos1==1) ban+=(k<=lim)*res[ww[1][j]][k];
    150                             else if(pos1==2) ban+=(k<=lim)*res[ww[2][p]][k];
    151                             else ban+=(k<=lim)*res[ww[3][q]][k];
    152                         }else if(fh==3){//>
    153                             if(pos1==0) ban+=(k>lim)*res[ww[0][i]][k];
    154                             else if(pos1==1) ban+=(k>lim)*res[ww[1][j]][k];
    155                             else if(pos1==2) ban+=(k>lim)*res[ww[2][p]][k];
    156                             else ban+=(k>lim)*res[ww[3][q]][k];
    157                         }else{//>=
    158                             if(pos1==0) ban+=(k>=lim)*res[ww[0][i]][k];
    159                             else if(pos1==1) ban+=(k>=lim)*res[ww[1][j]][k];
    160                             else if(pos1==2) ban+=(k>=lim)*res[ww[2][p]][k];
    161                             else ban+=(k>=lim)*res[ww[3][q]][k];
    162                         }
    163                     }
    164                     f[tim][i][j][p][q]+=(1.0-ban)*f[tim-1][i][j][p][q];
    165                     for(int k=0,now;k<=2*val;++k){
    166                         if(pos2==0){
    167                             if(i+flag*k<=0) continue;
    168                             now=min(8,i+flag*k);
    169                             f[tim][now][j][p][q]+=ban*f[tim-1][i][j][p][q]*res[val][k];
    170                         }else if(pos2==1){
    171                             if(j+flag*k<=0) continue;
    172                             int now=min(8,j+flag*k);
    173                             f[tim][i][now][p][q]+=ban*f[tim-1][i][j][p][q]*res[val][k];
    174                         }else if(pos2==2){
    175                             if(p+flag*k<=0) continue;
    176                             now=min(8,p+flag*k);
    177                             f[tim][i][j][now][q]+=ban*f[tim-1][i][j][p][q]*res[val][k];
    178                         }else{
    179                             if(q+flag*k<=0) continue;
    180                             now=min(8,q+flag*k);
    181                             f[tim][i][j][p][now]+=ban*f[tim-1][i][j][p][q]*res[val][k];
    182                         }
    183                     }
    184                 }
    185             }
    186         }
    187     }
    188 }
    189 int main(){
    190     res[0][0]=1.0;
    191     for(int i=1;i<=8;++i){
    192         for(int j=0;j<3;++j)
    193             for(int k=j;k<=16;++k)
    194                 res[i][k]+=res[i-1][k-j]/3.0;
    195     }
    196     for(int i=0;i<4;++i){
    197         scanf("%s",ch+1);
    198         for(int j=1;j<=8;++j)
    199             ww[i][j]=ch[j]-'0';
    200         scanf("%d",&p[i]);
    201     }
    202     f[0][p[0]][p[1]][p[2]][p[3]]=100.0;
    203     scanf("%d",&n);
    204     for(int i=1;i<=n;++i){
    205         scanf("%s",ch+1);
    206         int j=cal();
    207         scanf("%s",ch+1);
    208         int len=strlen(ch+1);
    209         if(len==2&&ch[1]!='>'&&ch[1]!='<'){
    210             int flag=(ch[1]=='+')?1:-1;
    211             int val=ch[2]-'0';
    212             work1(i,j,flag*val);
    213         }else if(len==3){
    214             int flag=(ch[1]=='+')?1:-1;
    215             int val=ch[2]-'0';
    216             work2(i,j,flag,val);
    217         }else{
    218             int fh=calc(),lim,k;
    219             scanf("%d%s",&lim,ch+1);
    220             k=cal();
    221             scanf("%s",ch+1);
    222             int len=strlen(ch+1);
    223             int flag=(ch[1]=='+')?1:-1;
    224             int val=ch[2]-'0';
    225             if(len==2) work3(i,j,fh,lim,k,flag,val);
    226             else work4(i,j,fh,lim,k,flag,val);
    227         }
    228     }
    229     for(int k=0;k<4;++k){
    230         for(int i=1;i<=8;++i)
    231             for(int j=1;j<=8;++j)
    232                 for(int p=1;p<=8;++p)
    233                     for(int q=1;q<=8;++q){
    234                         if(k==0) ans[0][ww[0][i]]+=f[n][i][j][p][q];
    235                         if(k==1) ans[1][ww[1][j]]+=f[n][i][j][p][q];
    236                         if(k==2) ans[2][ww[2][p]]+=f[n][i][j][p][q];
    237                         if(k==3) ans[3][ww[3][q]]+=f[n][i][j][p][q];
    238                     }
    239     }
    240     for(int i=1;i<=8;++i) dead+=ans[0][i];
    241     dead=100.0-dead;
    242     printf("%0.2lf
    ",dead);
    243     for(int k=0;k<4;++k){
    244         for(int i=1;i<=8;++i)
    245             printf("%0.2lf ",ans[k][i]);
    246         puts("");
    247     }
    248     return 0;
    249 }
    View Code

    彩球问题:记忆化搜索+高精

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 using namespace std;
     7 int n,k[20],n1,n2,n3;
     8 bool vis[20][20][20][20];
     9 struct bigint{
    10     int m[105];
    11     bigint(){
    12         memset(m,0,sizeof(m));
    13         m[0]=1;
    14     }
    15     friend bigint operator + (bigint a,bigint b){
    16         int x=0;
    17         bigint c;
    18         c.m[0]=max(a.m[0],b.m[0]);
    19         for(int i=1;i<=a.m[0]||i<=b.m[0];++i){
    20             c.m[i]=a.m[i]+b.m[i]+x;
    21             x=c.m[i]/10;
    22             c.m[i]%=10;
    23         }
    24         while(x) c.m[++c.m[0]]=x%10,x/=10;
    25         return c;
    26     }
    27     friend void operator += (bigint &a,bigint b){
    28         a=a+b;
    29     }
    30     friend bigint operator * (int a,bigint b){
    31         int x=0;
    32         bigint c;
    33         c.m[0]=b.m[0];
    34         for(int i=1;i<=b.m[0];++i){
    35             c.m[i]=b.m[i]*a+x;
    36             x=c.m[i]/10;
    37             c.m[i]%=10;
    38         }
    39         while(x) c.m[++c.m[0]]=x%10,x/=10;
    40         return c;
    41     }
    42 }f[20][20][20][20];
    43 void print(bigint a){
    44     for(int i=1;i<=a.m[0];++i){
    45         printf("%lld",a.m[a.m[0]-i+1]);
    46     }
    47     puts("");
    48 }
    49 bigint dfs(int i,int j,int k,int x){
    50     bigint res;
    51     res.m[0]=res.m[1]=1;
    52     if(i+j+k==0) return res;
    53     if(vis[i][j][k][x]) return f[i][j][k][x];
    54     bigint ans;
    55     if(i) ans+=(i-(x==2))*dfs(i-1,j,k,1);
    56     if(j) ans+=(j-(x==3))*dfs(i+1,j-1,k,2);
    57     if(k) ans+=(k-(x==4))*dfs(i,j+1,k-1,3);
    58     vis[i][j][k][x]=1;
    59     return f[i][j][k][x]=ans;
    60 }
    61 signed main(){
    62     scanf("%lld",&n);
    63     for(int i=1;i<=n;++i){
    64         scanf("%lld",&k[i]);
    65         n1+=(k[i]==1);
    66         n2+=(k[i]==2);
    67         n3+=(k[i]==3);
    68     }
    69     print(dfs(n1,n2,n3,0));
    70     return 0;
    71 }
    View Code

    邻面合并:

    状压dp

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 int n,m,a[105][15],ans=0x3f3f3f3f;
      7 int b[105],f[105][(1<<9)+5];
      8 bool judge(int now,int sta){
      9     bool flag=0;
     10     for(int i=1;i<=m;++i){
     11         if(sta&(1<<(i-1))) flag=1;
     12         if(a[now][i]==1&&flag==0) return 0;
     13         if(!a[now][i]) flag=0;
     14         if((sta&(1<<(i-1)))&&a[now][i]==0) return 0;
     15     }
     16     return 1;
     17 }
     18 int lowbit(int x){
     19     return x&-x;
     20 }
     21 int cal(int sta){
     22     int res=0;
     23     while(sta>0){
     24         sta-=lowbit(sta);
     25         ++res;
     26     }
     27     return res;
     28 }
     29 int main(){
     30     scanf("%d%d",&n,&m);
     31     for(int i=1;i<=n;++i){
     32         for(int j=1;j<=m;++j){
     33             scanf("%d",&a[i][j]);
     34             b[i]|=(a[i][j]<<(j-1));
     35         }
     36     }
     37     memset(f,0x3f,sizeof(f));
     38     f[0][0]=0;
     39     for(int i=1;i<=n;++i){
     40         for(int s1=0;s1<(1<<m);++s1){
     41             if(!judge(i,s1)) continue;
     42             for(int s2=0;s2<(1<<m);++s2){
     43                 if(!judge(i-1,s2)) continue;
     44                 int cnt=cal(s1);
     45                 for(int j=1;j<=m;++j){
     46                     if((s1&(1<<(j-1)))&&(s2&(1<<(j-1)))){
     47                         int pos=j;
     48                         while(pos<=m&&a[i][pos]){
     49                             if(pos!=j&&(s1&(1<<(pos-1)))) break;
     50                             ++pos;
     51                         }
     52                         --pos;
     53                         bool flag=0;
     54                         if(!(s2&(1<<pos)||(!a[i-1][pos+1]))) flag=1;
     55                         for(int k=j+1;k<=pos;++k){
     56                             if(flag) break;
     57                             if((s2&(1<<(k-1)))||(!a[i-1][k])) flag=1;
     58                         }
     59                         if(!flag) --cnt;
     60                     }
     61                 }
     62                 f[i][s1]=min(f[i][s1],f[i-1][s2]+cnt);
     63                 if(i==n) ans=min(ans,f[i][s1]);
     64             }
     65         }
     66     }
     67     printf("%d
    ",ans);
     68     return 0;
     69 }
     70 /*
     71 4 4
     72 1 1 1 0
     73 1 1 0 1
     74 0 0 1 1
     75 0 0 1 1
     76 4
     77 
     78 4 4
     79 1 1 1 0
     80 0 1 1 1
     81 0 1 1 1
     82 0 1 1 1
     83 2
     84 
     85 5 4
     86 1 1 0 1
     87 1 1 1 1
     88 1 1 0 1
     89 0 0 1 1
     90 0 0 1 1
     91 4
     92 
     93 8 4
     94 1 1 1 1
     95 0 1 0 0
     96 0 1 0 0
     97 1 1 1 0
     98 1 1 1 0
     99 1 1 1 1
    100 0 1 1 1
    101 0 0 1 1
    102 5
    103 
    104 8 4
    105 1 1 1 1
    106 0 1 1 0
    107 0 1 0 0
    108 1 1 1 0
    109 1 1 1 0
    110 1 1 1 1
    111 0 1 1 1
    112 0 0 1 1
    113 6
    114 
    115 4 11
    116 1 1 1 0 1 1 0 0 1 0 0
    117 1 1 0 0 1 1 0 0 1 1 0
    118 1 0 0 0 1 0 0 0 1 1 1
    119 1 1 1 1 1 0 0 1 1 0 0
    120 */
    View Code

    123567:

    杜教筛,啥都不会

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<unordered_map>
     6 #include<cmath>
     7 #define re register
     8 using namespace std;
     9 long long n,ans;
    10 int N,prime[7000005],tot=0;
    11 unordered_map<int,int>mp;
    12 short mu[10000005];
    13 bool vis[10000005];
    14 inline void get_mu(re int N){
    15     vis[1]=mu[1]=1;
    16     for(re int i=2;i<=N;++i){
    17         if(!vis[i]) prime[++tot]=i,mu[i]=-1;
    18         for(re int j=1;i*prime[j]<=N;++j){
    19             vis[i*prime[j]]=1;
    20             if(!(i%prime[j])) break;
    21             mu[i*prime[j]]=-mu[i];
    22         }
    23         mu[i]+=mu[i-1];
    24     }
    25 }
    26 inline int sum(re int x){
    27     if(x<=N) return mu[x];
    28     if(mp.find(x)!=mp.end()) return mp[x];
    29     re int res=1;
    30     for(re int l=2,r;l<=x;l=r+1){
    31         r=x/(x/l);
    32         res=res-sum(x/r)*(r-l+1);
    33     }
    34     return mp[x]=res;
    35 }
    36 signed main(){
    37     scanf("%lld",&n);
    38     N=min(1e7,sqrt(n));
    39     get_mu(N);
    40     for(re long long l=1,r;l*l<=n;l=r+1){
    41         r=sqrt(n/(n/(l*l)));
    42         ans=ans+n/(r*r)*(sum(r)-sum(l-1));
    43     }
    44     printf("%lld
    ",ans);
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    周末复习所接触到的知识点
    新增一些需要记住的知识点和坑
    讨厌烦人的编码问题''
    dictionary 字典相关操作
    一些列表的基础知识和操作
    简单字符串语句
    一些简单的str语句
    c#学习之前言
    第六课时之HTML标题
    第五课时之HTML属性
  • 原文地址:https://www.cnblogs.com/Juve/p/11752563.html
Copyright © 2020-2023  润新知