• [IOI2007]Miners


    [IOI2007]Miners

    题目大意:

    两个人吃东西,总共有(3)种食物,每个人每次吃到食物时可以获得的收益是当前食物和前两次吃的食物中,不同食物的种数。现在给定一个长度为(n(nle10^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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    近期C#小问题总结
    Arcgis由栅格数据提取等值线
    Arcgis由离散点制作核密度图
    用Arcgis为离散点区域生成格网(渔网)
    Arcengine合并面要素
    对离散点进行抽稀
    对离散点进行区域分割
    关于异常来自 HRESULT:0x80040351
    分布式缓存---Memcached 入门
    Mongodb安装 for windows7 64位
  • 原文地址:https://www.cnblogs.com/skylee03/p/9502532.html
Copyright © 2020-2023  润新知