码迷,mamicode.com
首页 > 其他好文 > 详细

[IOI2007]Miners

时间:2018-08-19 21:58:26      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:while   getch   tchar   mat   序列   reg   现在   its   getc   

[IOI2007]Miners

题目大意:

两个人吃东西,总共有\(3\)种食物,每个人每次吃到食物时可以获得的收益是当前食物和前两次吃的食物中,不同食物的种数。现在给定一个长度为\(n(n\le10^5)\)的食物序列,按顺序每次将这些食物分配给两个人中的一个。问收益总和的最大值。

思路:

\(f[i][j][k][l][m]\)表示分完前\(i\)个吃的,\(A\)最后两个吃了\(i\)\(j\)\(B\)最后两个吃了\(l\)\(m\)时的最大收益。

时间复杂度\(\mathcal O(4^4n)\)

为了防止MLE需要使用滚动数组。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
inline int getfood() {
    register char ch;
    while(!isalpha(ch=getchar()));
    if(ch=='M') return 1;
    if(ch=='F') return 2;
    if(ch=='B') return 3;
    return 0;
}
const int N=1e5+1;
int f[2][4][4][4][4];
inline void up(int &x,const int &y) {
    x=std::max(x,y);
}
inline int calc(int x,int y,const int &z) {
    x=x?:z;
    y=y?:z;
    if(x==y&&y==z) return 1;
    if(x==y&&y!=z) return 2;
    if(x==z&&z!=y) return 2;
    if(y==z&&x!=y) return 2;
    return 3;
}
int main() {
    const int n=getint();
    for(register int j=0;j<4;j++) {
        for(register int k=0;k<4;k++) {
            for(register int l=0;l<4;l++) {
                for(register int m=0;m<4;m++) {
                    f[0][j][k][l][m]=INT_MIN;
                }
            }
        }
    }
    f[0][0][0][0][0]=0;
    for(register int i=1;i<=n;i++) {
        const bool cur=i&1;
        const int x=getfood();
        for(register int j=0;j<4;j++) {
            for(register int k=0;k<4;k++) {
                for(register int l=0;l<4;l++) {
                    for(register int m=0;m<4;m++) {
                        f[cur][j][k][l][m]=INT_MIN;
                    }
                }
            }
        }
        for(register int j=0;j<4;j++) {
            for(register int k=0;k<4;k++) {
                for(register int l=0;l<4;l++) {
                    for(register int m=0;m<4;m++) {
                        if(f[cur^1][j][k][l][m]==INT_MIN) continue;
                        up(f[cur][k][x][l][m],f[cur^1][j][k][l][m]+calc(j,k,x));
                        up(f[cur][j][k][m][x],f[cur^1][j][k][l][m]+calc(l,m,x));
                    }
                }
            }
        }
    }
    int ans=0;
    for(register int j=0;j<4;j++) {
        for(register int k=0;k<4;k++) {
            for(register int l=0;l<4;l++) {
                for(register int m=0;m<4;m++) {
                    up(ans,f[n&1][j][k][l][m]);
                }
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

[IOI2007]Miners

标签:while   getch   tchar   mat   序列   reg   现在   its   getc   

原文地址:https://www.cnblogs.com/skylee03/p/9502532.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!