hrb 1476 动态规划

题意:

  n个单词,每行字符数量m个,单行字符数量值为j时,花费我 (m-j)^3

  单词间有一个空格,问最小花费。 最后一行不花费

解法

  dp[i][j] 表示前i个单词,长度为j的最小花费

  

// 最后一行多余空格不作为计算,只有出现换行时才计算。

// dp[i][j] 表示前i个单词,长度为j的最小整齐度
// 由 dp[i][j] 通过添加一个 单词 L[i+1] 只可能导致两种情况
// 1, 依然在一行,此时应满足条件
// 若 j == 0 ,则此时必定可以添加到后面有
// dp[i+1][ L[i+1] ] = Min{ dp[i][j] }
// 若 j > 0 , 则此时需满足 j+1+L[i+1] 有
// dp[i=1][ j+1+L[i+1] ] = Min{ dp[i][j] }
// 2, 若换行,此时应满足条件 j > 0
// dp[i+1][ L[i+1] ] = Min{ dp[i][j] + (M-j)^3 }

View Code
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define cmp(x) (x)*(x)*(x)
typedef unsigned long long LL;
const LL inf = ~0u>>1;
// 最后一行多余空格不作为计算,只有出现换行时才计算。 

// dp[i][j] 表示前i个单词,长度为j的最小整齐度
// 由 dp[i][j] 通过添加一个 单词 L[i+1] 只可能导致两种情况
//        1, 依然在一行,此时应满足条件     
//            若 j == 0 ,则此时必定可以添加到后面有
//                dp[i+1][ L[i+1] ] = Min{ dp[i][j] }
//            若 j  > 0 , 则此时需满足 j+1+L[i+1] 有 
//                 dp[i=1][ j+1+L[i+1] ] = Min{ dp[i][j] }
//        2, 若换行,此时应满足条件 j > 0
//            dp[i+1][ L[i+1] ] = Min{ dp[i][j] + (M-j)^3 } 
LL dp[2][510];
int L[2010];
int n, m;
void DP(){
//    memset( dp, 0xff, sizeof(dp) );
    for(int i = 0; i < m; i++) dp[0][i] = inf;
    dp[0][0] = 0;
    for(int i = 0; i < n; i++){
        int cur = i&1, nxt = (i+1)&1;
        for(int j = 0; j < m; j++) dp[nxt][j] = -1; 
        for(int j = 0; j < m; j++){
            if( (dp[cur][j] != -1)   ){ 
                if( j == 0 ){
                    int len = (j+L[i+1] == m )? 0 : j+L[i+1];
                //    if( dp[nxt][len] == -1 ) dp[nxt][len] = dp[cur][j];
                //    else dp[nxt][len] = min( dp[nxt][len], dp[cur][j] );    
                    dp[nxt][len] = min( dp[nxt][len], dp[cur][j] );
                }
                else if( j+1+L[i+1] <= m ){
                    int len = (j+1+L[i+1] == m) ? 0 : j+1+L[i+1];
                    if( len < m ){
                    //    if( dp[nxt][len] == -1 ) dp[nxt][len] = dp[cur][j];
                    //    else dp[nxt][len] = min( dp[nxt][len], dp[cur][j] );    
                        dp[nxt][len] = min( dp[nxt][len], dp[cur][j] );
                    }
                }  
                if( j > 0 ){
                //    if( dp[nxt][ L[i+1] ] == -1 ) 
                //        dp[nxt][ L[i+1] ] = dp[cur][j] + cmp(m-j);
                //    else
                        dp[nxt][ L[i+1] ] = min( dp[nxt][ L[i+1] ], dp[cur][j] + cmp(m-j) );
                }
            } 
        }     
    } 
    LL ans = inf;
    for(int i = 0; i < m; i++){
        if( dp[ n&1 ][i] != -1 ){
            if( ans == -1 ) ans = dp[n&1][i];
            else ans = min( ans, dp[n&1][i] );    
        } 
    }
    printf("%llu\n", ans );
}

int main(){
    while( scanf("%d%d", &n,&m) != EOF){
        for(int i = 1; i <= n; i++)
            scanf("%d", &L[i] );
        DP();    
    } 
    return 0;    
}
原文地址:https://www.cnblogs.com/yefeng1627/p/3012920.html