[IOI2007]矿工配餐

状态是f[i][a][b][c][d]表示第i个餐车,1号矿洞最近两顿是a,b,2号矿洞最近两顿是c,d。
给的空间是16MB,滚动数组滚动了第一维就行了
(给的变量是char是因为这个不超过256,但是并没有快多少

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,f[2][4][4][4][4];
char s[100005];
inline char fy(char c) {
    if(c=='M') return 1;
    if(c=='F') return 2;
    if(c=='B') return 3;
}
inline char mei(short a,short b,short c) {
    register char tp=1;
    if(a!=b&&a!=c&&a) tp++;
    if(b!=c&&b) tp++;
    return tp;
}
int main() {
    scanf("%d",&n);
    scanf("%s",s+1);
    memset(f,-1,sizeof f);
    f[0][0][0][0][0]=0;
    register int i;register char j,k,l,m,t;
    for(i=1;i<=n;i++) {
        for(j=0;j<4;j++) 
            for(k=0;k<4;k++) 
                for(l=0;l<4;l++) 
                    for(m=0;m<4;m++) {
                        if(f[i+1&1][j][k][l][m]==-1) continue;
                        t=fy(s[i]);
                        f[i&1][k][t][l][m]=max(f[i&1][k][t][l][m],f[i+1&1][j][k][l][m]+mei(j,k,t));
                        f[i&1][j][k][m][t]=max(f[i&1][j][k][m][t],f[i+1&1][j][k][l][m]+mei(l,m,t));
                    }
        memset(f[i+1&1],-1,sizeof f[0]);
    }
    int ans=0;
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
            for(k=0;k<4;k++)
                for(l=0;l<4;l++) 
                    ans=max(ans,f[n&1][i][j][k][l]);
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/sdfzhsz/p/9816339.html