zoukankan      html  css  js  c++  java
  • 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;    
    }
  • 相关阅读:
    磊哥评测之数据库:腾讯云MongoDB vs自建
    一文看透浏览器架构
    必看!如何让你的LBS服务性能提升十倍!
    亿级曝光品牌视频的幕后设定
    Node 框架接入 ELK 实践总结
    大数据与 AI 生态中的开源技术总结
    数据库分片(Database Sharding)详解
    QQ音乐的动效歌词是如何实践的?
    Sql Server之旅——第九站 看公司这些DBA们设计的这些复合索引
    Sql Server之旅——第八站 复合索引和include索引到底有多大区别?
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/3012920.html
Copyright © 2011-2022 走看看