zoukankan      html  css  js  c++  java
  • UVA 709 Formatting Text

    UVA_709

        我们不妨用f[i]表示某行到第i个单词结束时的最小的badness,这样f[i]=min{f[i-1]+500,f[j]+badness},当然j+1到i这些单词必须能在这一行放得下。

        之后我们不妨先考虑下对于一行而言,单词要怎么摆才最优。不难证明,各个空白的长度差越小越好,并且长度小的空白排在前面。

        接下来,我们还要保证全文在满足badness最优的情况下,空白也得最优。如果空白最优,仅就到第i个单词而言,显然行数越少越优,在行数相等的情况下,显然第i个单词所在的这一行的单词数越少越优,于是我们再引入一个记录行数的数组s[]即可。

        题目中提到过如果一行只有一个单词,仅输出这个单词即可,不要在后面补空格,否则会PE。

    #include<stdio.h>
    #include<string.h>
    #include<ctype.h>
    #define MAXN 90
    #define MAXD 10010
    int N, M, f[MAXD], s[MAXD], len[MAXD], p[MAXD], n[3][MAXD];
    char b[MAXD], word[MAXD][MAXN];
    int init()
    {
    int i, j, k;
    gets(b);
    if(b[0] == '0')
    return 0;
    sscanf(b, "%d", &N);
    M = 0;
    for(;;)
    {
    gets(b);
    if(b[0] == '\0')
    break;
    for(i = 0; b[i];)
    {
    if(b[i] == ' ')
    {
    i ++;
    continue;
    }
    ++ M;
    for(j = 0; b[i] != '\0' && b[i] != ' '; i ++, j ++)
    word[M][j] = b[i];
    word[M][j] = '\0';
    len[M] = j;
    }
    }
    return 1;
    }
    void printpath(int last)
    {
    int i, j, k, first = p[last];
    if(first)
    printpath(first);
    if(first + 1 == last)
    printf("%s", word[last]);
    else
    {
    j = first + 1;
    for(i = 0; i < n[0][last]; i ++)
    {
    printf("%s", word[j ++]);
    for(k = 0; k < n[3][last]; k ++)
    printf(" ");
    }
    for(i = 0; i < n[1][last]; i ++)
    {
    printf("%s", word[j ++]);
    for(k = 0; k <= n[3][last]; k ++)
    printf(" ");
    }
    printf("%s", word[j]);
    }
    printf("\n");
    }
    void solve()
    {
    int i, j, k, n1, n2, total, bad;
    if(!M)
    return;
    memset(f, 0x3f, sizeof(f));
    memset(s, 0x3f, sizeof(s));
    f[0] = s[0] = 0;
    for(i = 0; i < M; i ++)
    {
    if(f[i] + 500 < f[i + 1])
    {
    f[i + 1] = f[i] + 500;
    p[i + 1] = i;
    s[i + 1] = s[i] + 1;
    }
    total = len[i + 1];
    for(j = i + 2; j <= M; j ++)
    {
    total += len[j];
    if(total + j - i - 1 > N)
    break;
    k = (N - total) / (j - i - 1);
    n2 = N - total - k * (j - i - 1);
    n1 = j - i - 1 - n2;
    bad = n1 * (k - 1) * (k - 1) + n2 * k * k;
    if(f[i] + bad < f[j] || (f[i] + bad == f[j] && s[i] + 1 <= s[j]))
    {
    f[j] = f[i] + bad;
    p[j] = i;
    n[0][j] = n1, n[1][j] = n2, n[3][j] = k;
    s[j] = s[i] + 1;
    }
    }
    }
    printpath(M);
    }
    int main()
    {
    while(init())
    {
    solve();
    printf("\n");
    }
    return 0;
    }


  • 相关阅读:
    HashCode的作用
    为什么重写equals一定要重写hashcode?
    java timer 定时器原理
    java内部类作用
    jeesite添加多数据源
    Eclipse之安装Jadclipse插件直接查看class文件
    NIO和IO的主要区别
    sql 语句
    HTTP Error 500.0
    基于.NetCore3.1系列 ——认证授权方案之Swagger加锁
  • 原文地址:https://www.cnblogs.com/staginner/p/2279059.html
Copyright © 2011-2022 走看看