zoukankan      html  css  js  c++  java
  • [SCOI2009]粉刷匠

    题目

      点这里看题目。

    分析

      首先可以考虑一个比较粗糙的大 DP :
      (f(i,j)):前(i)行,刷(j)次,最多能刷的正确格子数。
      转移是一个背包:

    [f(i,j)=max_{1le kle m}{f(i-1,j-k)+con(i,k)} ]

      其中(con(i,k))表示第(i)行刷(k)次最多能刷的正确格子数。
      我们发现,由于(con)是按行独立的,因此对于每行我们可以再做一次 DP 处理出(con)
      对于第(i)行,我们有如下的 DP :
      (g(j,k)):前(j)个格子刷(k)次最多能刷的正确格子数。
      设(mx(j,k))为第(i)行刷一次区间([j,k])最多能刷的正确格子数,也就是区间内数量最多的颜色的数量。
      转移显然:

    [g(j,k)=max_{0le l< j}{g(l,k-1)+mx(l+1,j)} ]

      内层 DP 一次(O(m^3)),做(n)次就是(O(nm^3));外层 DP (O(nmT))。总时间(O(nm^3+nmT))

    代码

    #include <cstdio>
    
    const int INF = 0x3f3f3f3f;
    const int MAXN = 55, MAXM = 55, MAXT = 2505;
    
    template<typename _T>
    void read( _T &x )
    {
    	x = 0;char s = getchar();int f = 1;
    	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
    	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
    	x *= f;
    }
    
    template<typename _T>
    void write( _T x )
    {
    	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
    	if( 9 < x ){ write( x / 10 ); }
    	putchar( x % 10 + '0' );
    }
    
    template<typename _T>
    _T MAX( const _T a, const _T b )
    {
    	return a > b ? a : b;
    }
    
    int g[MAXM][MAXM], f[MAXT];
    int col[MAXN][MAXM];
    int N, M, T;
    
    int main()
    {
    	read( N ), read( M ), read( T );
    	for( int i = 1 ; i <= N ; i ++ )
    		for( int j = 1 ; j <= M ; j ++ )
    			scanf( "%1d", &col[i][j] );
    	for( int i = 1 ; i <= T ; i ++ ) f[i] = -INF;
    	for( int i = 1 ; i <= M ; i ++ ) g[0][i] = -INF;
    	for( int i = 1 ; i <= N ; i ++ )
    	{
    		for( int j = 1 ; j <= M ; j ++ )
    			for( int k = 1 ; k <= j ; k ++ )
    			{
    				g[j][k] = -INF; int cnt[2] = {};
    				for( int l = j - 1 ; ~ l ; l -- )
    					cnt[col[i][l + 1]] ++, g[j][k] = MAX( g[j][k], g[l][k - 1] + MAX( cnt[0], cnt[1] ) );
    			}
    		for( int j = T ; j ; j -- )
    			for( int k = 1 ; k <= M && k <= j ; k ++ )
    				f[j] = MAX( f[j], f[j - k] + g[M][k] );
    	}
    	write( f[T] ), putchar( '
    ' );
    	return 0;
    }
    
  • 相关阅读:
    weekly review 200930: Battlestar Galactica
    weekly review 200926: loss memory
    weekly review 200924: LOST
    转贴:对话守则
    weekly review 200928: Return
    推荐:继续聚焦小升初——破解奥数迷题
    Centos+Nginx部署Vue项目
    centos7安装nginx
    flaskmigrate 处理sqlite数据库报错Constraint must have a name 的解决方案
    将阿里矢量图添加到elementui
  • 原文地址:https://www.cnblogs.com/crashed/p/12827923.html
Copyright © 2011-2022 走看看