csps模拟87888990部分题解

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

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

模拟87:ios

mazeide

在实数上二分,跑最短路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\n",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\n",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\n",ans);
107     return 0;
108 }
View Code

bird:spa

 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\n",ans);
80     return 0;
81 }
View Code

stone:3d

 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\n",ans);
41     return 0;
42 }
View Code

模拟88:code

军训队列:htm

排序必定不会更劣,blog

设f[i][j]表示前i个分了j个队列的最小值,则有方程:$f[i][j]=min(f[p][j-1]+(a[i]-a[p])^2),p\in[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\n",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\n",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\n",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\n",ans);
45     return 0;
46 }
View Code