group: shape pressure dp, contour

Immortal title. But rare Silly boy did not call cbx solution to a problem, so it is rare so they want out of a fairy theme.

If they want, it is a little fairy inappropriate ah. . ?

Anyway, it does not like. The key lies in the label. Decadent almost finished label would.

%%% cbx was thought out so fast. (2 hours?)

 

Much nonsense.

 

Consider violence. Of course, the data range to be considered like a 16 pressed, the state of each location indicates whether to put the soldiers.

We need only consider the left, above the right to contribute to the bottom, and finally the answer to × 2.

Then enumerate the status of each layer, layer by layer transfer can be.

Complexity is $ O ((2 ^ {C}) ^ 2 \ times C \ times R) $, approximately 9e12

I think with a little optimization, since you already know the number of soldiers in this layer, then those states where illegal would not have enumerated.

Pretreatment around it, the complexity is $ O ((C_C ^ {C / 2}) ^ 2 \ times C \ times R) $, extreme case 3e11

But I do not think, one point will not be much.

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<iostream>
 5 using namespace std;
 6 int r,c,num[129],dp[2][1048577],re[1048577][17],loc[1048577][17],scnt[1048577],ANS;
 7 char s[129][18];
 8 vector<int>v[17];
 9 int cal(int ro,int lst,int tst){
10     int ans=0;
11     for(int i=1;i<scnt[tst];++i)if(loc[tst][i]+1==loc[tst][i+1]&&s[ro][i]==s[ro][i+1])ans++;
12     for(int i=1;i<=c;++i)if(lst&1<<i-1&&tst&1<<i-1&&s[ro-1][re[lst][i]]==s[ro][re[tst][i]])ans++;
13     return ans;
14 }
15 int main(){
16     scanf("%d%d",&r,&c);
17     for(int i=1;i<=r;++i)scanf("%s",s[i]+1),num[i]=strlen(s[i]+1);
18     for(int i=0;i<1<<c;++i){
19         int cnt=0,j=i,alm=0;
20         while(j)j^=j&-j,cnt++;
21         scnt[i]=cnt;
22         v[cnt].push_back(i);
23         for(int k=1;k<=c;++k)re[i][k]=re[i][k-1]+(i&1<<k-1?1:0);
24         for(int k=1;k<=c;++k)if(i&1<<k-1)loc[i][++alm]=k;
25     }//printf("%d\n",v[1][0]);
26     for(int i=1;i<=r;++i){
27         memset(dp[i&1],0,sizeof dp[i&1]);
28         for(int j=0;j<v[num[i-1]].size();++j)for(int k=0;k<v[num[i]].size();++k)
29             dp[i&1][v[num[i]][k]]=max(dp[i&1][v[num[i]][k]],dp[i&1^1][v[num[i-1]][j]]+cal(i,v[num[i-1]][j],v[num[i]][k]));
30     }
31     for(int i=0;i<=v[num[r]].size();++i)ANS=max(ANS,dp[r&1][v[num[r]][i]]);
32     printf("%d\n",ANS<<1);//printf("%d\n",cal(2,1,1));
33 }
Used as a shot T40

 

Significant bottleneck lies in the complexity of $ C_ {16} ^ 8 $ or $ 2 ^ {16} $ on the square, like the pressure is certainly indispensable, but there is not square.

That is a must enumerate only a transfer of state.

Find this question of the special nature, if considered in turn each grid, then dp value is increased with only one left and one top about.

So you enumerate a whole floor above is superfluous.

As long as we know this one's own, to the left and above who like the rest position and do not care.

And after this one filled out, above the one who will set aside, replaced by this one. . .

So our state is represented by each of the current contour line has not put numbers. . .

Specific implementation is quite simple. Need to be modified a bit in binary, binary judgment about a bit in each of several 1 (know what number it can be judged in the end who is a)

Labeled as a function, a pretreatment.

Complexity $ O (2 ^ C \ times C \ times R) $

Note that to get rid of illegal state (the number of which was found enough to fill several or more after his party finished)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 char s[129][18];int n,m,dp[2][65538],cntl[65538][18],cntr[65538][18],ans,l[129];
 6 int chg(int st,int p,int w){
 7     if(!p)return st>>1<<1|w;
 8     int r=st&(1<<p)-1;
 9     st>>=p+1;st<<=1;st|=w;st<<=p;//printf("%d\n",st);
10     return st|r;
11 }
12 int main(){
13     scanf("%d%d",&n,&m);
14     for(int i=1;i<=n;++i)scanf("%s",s[i]+1),l[i]=strlen(s[i]+1);
15     for(int i=0;i<1<<m;++i){
16         for(int j=2;j<=m+1;++j)cntl[i][j]=cntl[i][j-1]+(i&1<<j-2?1:0);
17         for(int j=m-1;j;--j)cntr[i][j]=cntr[i][j+1]+(i&1<<j?1:0);
18     //    for(int j=1;j<=m;++j)printf("%d %d %d %d\n",i,j,cntl[i][j],cntr[i][j]);
19     }//return 0;
20     int nw=1,ls=0;memset(dp[nw],0xa0,sizeof dp[nw]);dp[nw][0]=0;
21     for(int i=1;i<=n;++i){
22         for(int j=1;j<=m;++j){
23             nw^=1;ls^=1;memset(dp[nw],0xa0,sizeof dp[nw]);
24             for(int st=0;st<1<<m;++st){
25                 char sl=s[i][cntl[st][j]],su=s[i-1][l[i-1]-cntr[st][j]],sT=s[i][cntl[st][j]+1];//printf("%d %d %d %c %c %c\n",i,j,st,sT,sl,su);
26                 if(!(st&1<<j-2))sl=0;if(!(st&1<<j-1))su=0;
27                 if(sT)dp[nw][chg(st,j-1,1)]=max(dp[nw][chg(st,j-1,1)],dp[ls][st]+(sl==sT)+(sT==su));
28                 dp[nw][chg(st,j-1,0)]=max(dp[nw][chg(st,j-1,0)],dp[ls][st]);
29             }
30     //        for(int s=0;s<1<<m;++s)printf("%d %d %d %d\n",i,j,s,dp[nw][s]);
31         }
32         for(int st=0;st<1<<m;++st)if(cntl[st][m+1]!=l[i])dp[nw][st]=0xa0a0a0a0;
33     //    int j=m;for(int s=0;s<1<<m;++s)printf("%d %d %d %d\n",i,j,s,dp[nw][s]);
34     }
35     for(int i=0;i<1<<m;++i)ans=max(ans,dp[nw][i]);
36     printf("%d\n",ans*2);//printf("%d\n",chg(1,3,1));
37 }
View Code

Cbx did not say so well-written tune.

Small sample pan easily he gives:

2 1 A A

2 2 A A

3 3 AB AA BA (this is my pan)

 

Guess you like

Origin www.cnblogs.com/hzoi-DeepinC/p/11572842.html