zoukankan      html  css  js  c++  java
  • 【bzoj1806】[Ioi2007]Miners 矿工配餐 dp

    题目描述

    有n个物品,每个都是3种之一。现要将这n个物品分成两个序列,对于每个序列中的每个物品,可以得到 它及它前面相邻的两个物品(不足则取全部)中不同种类的个数 的收益。问最大的总收益。

    输入

    输入的第一行包含一个整数N (1 ≤ N ≤ 100 000), 表示食品车的数目。 第二行包含一个由N个字符组成的字符串,按照配送顺序依次表示食品车配送的食品的类型。每个字符是以下三个大写字母之一:'M' (表示肉类), 'F' (表示鱼类) 或 'B' (表示面包)。

    输出

    输出一个整数,表示最大的总产煤量。 评分 在45分的测试数据中,食品车的数目至多为20

    样例输入

    6
    MBMFFB

    样例输出

    12


    题解

    dp

    设$f[i][j][k][l][m]$表示前$i$个物品,第一个序列的最后一个是$j$,第一个序列的倒数第二个是$k$,第二个序列的最后一个是$l$,第二个序列的倒数第二个是$m$的最大总收益(物品不存在则为0)。

    那么每次只需要讨论当前物品放到哪个序列即可,状态转移方程详见代码。

    由于空间不足,所以需要滚动数组。

    时间复杂度$O(n*4^4)$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int f[2][4][4][4][4] , v[100010] , cnt[4];
    char s[100010];
    inline void gmax(int &x , const int y)
    {
    	x < y ? x = y : 0;
    }
    inline int calc(int a , int b , int c)
    {
    	cnt[1] = cnt[2] = cnt[3] = 0 , cnt[a] = 1 , cnt[b] = 1 , cnt[c] = 1;
    	return cnt[1] + cnt[2] + cnt[3];
    }
    int main()
    {
    	int n , d , i , j , k , l , m , ans = 0;
    	scanf("%d%s" , &n , s + 1);
    	for(i = 1 ; i <= n ; i ++ ) v[i] = (s[i] == 'M' ? 1 : s[i] == 'F' ? 2 : 3);
    	memset(f , 0xc0 , sizeof(f)) , f[0][0][0][0][0] = 0;
    	for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
    		for(j = 0 ; j <= 3 ; j ++ )
    			for(k = 0 ; k <= 3 ; k ++ )
    				for(l = 0 ; l <= 3 ; l ++ )
    					for(m = 0 ; m <= 3 ; m ++ )
    						gmax(f[d][v[i]][j][l][m] , f[d ^ 1][j][k][l][m] + calc(v[i] , j , k)) , gmax(f[d][j][k][v[i]][l] , f[d ^ 1][j][k][l][m] + calc(v[i] , l , m));
    	for(i = 0 ; i <= 3 ; i ++ )
    		for(j = 0 ; j <= 3 ; j ++ )
    			for(k = 0 ; k <= 3 ; k ++ )
    				for(l = 0 ; l <= 3 ; l ++ )
    					gmax(ans , f[n & 1][i][j][k][l]);
    	printf("%d
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    Linux/ visual studio 编译使用Poco
    无法安装 golang.org/x/tools/的库
    大牛blog汇总
    Redis整合Spring结合使用缓存实例
    js增加收藏
    iOS学习笔记12-网络(一)NSURLConnection
    Kick the ball!(dfs)湖南省赛第十届
    windows程序设计——飞机大战笔记(Access数据库的使用)
    DataGridView.DataSource= list(Of T)
    面试之SQL(1)--选出选课数量&gt;=2的学号
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7660050.html
Copyright © 2011-2022 走看看