zoukankan      html  css  js  c++  java
  • POJ 1093 Formatting Text

    最长上升子序列类动态规划

    dp[i] = min(dp[i],dp[j] + k)

    题意:给定若干单词,把它们排成每行字符数为n的若干行,词与词之间可填充任意个空格,设某个单词与单词之间的空格数为g,(g-1)^2称为坏点,

      求使所有坏点和最小得排版方式.


    技巧:因为要构造字母序最小的最优解,所以可以从后往前进行DP计算

    View Code
    #include<cstdio>
    #include<cstring>
    #define MAXN 10010
    using namespace std;
    
    char word[MAXN][82];
    int a[MAXN],aft[MAXN],b[MAXN],m,n;
    
    void Blank(int k)
    {
        for(;k--;)
            putchar(' ');
    }
    
    int Cal(int i, int j)
    {
        int g,t,k,ret;
        if(j==i+1)
            return 500;
        t=n-(a[i]-a[j]);
        k=j-i-1;
        g=t/k;
        ret=k*g*g+(t%k)*(2*g+1);
        return ret;
    }
    
    void Input()
    {
        int i,j,k;
        char s[100];
        gets(s);
        for(k=0;gets(s),s[0]!='\0';)
            for(i=0;s[i]!='\0'&&s[i]!='\n';)
            {
                while(s[i]==' ')
                    i++;
                if(s[i]=='\0'||s[i]=='\n')
                    break;
                for(j=0;s[i]!='\0'&&s[i]!='\n'&&s[i]!=' ';j++,i++)
                    word[k][j]=s[i];
                word[k++][j]='\0';
            }
        m=k;
        n++;
        a[m]=0;
        for(i=m-1;i>=0;i--)
            a[i]=(int)strlen(word[i])+1+a[i+1];
    }
    
    void Solve()
    {
        int i,j,k;
        b[m]=0;
        for(i=m-1;i>=0;i--)
        {
            b[i]=b[i+1]+500;
            aft[i]=i+1;
            for(j=i+2;j<=m&&a[i]-a[j]<=n;j++)
            {
                k=Cal(i,j);
                if(b[i]>b[j]+k||(b[i]==b[j]+k&&Cal(i,j)<Cal(i,aft[i])))
                    b[i]=b[j]+k,aft[i]=j;    
            }
        }
    }
    
    void Print()
    {
        int k,t,g,d,i,j;
        for(i=0;i<m;i=j)
        {
            j=aft[i];
            if(j==i+1)
            {
                printf("%s",word[i]);
                putchar('\n');
            }
            else
            {
                t=n-(a[i]-a[j]);
                k=j-i-1;
                g=t/k;
                d=k-(t%k);
                for(;d--;i++)
                {
                    printf("%s ",word[i]);
                    Blank(g);
                }
                for(;i+1<j;i++)
                {
                    printf("%s  ",word[i]);
                    Blank(g);
                }
                puts(word[i]);
            }
        }
    }
    
    int main()
    {
        for(;scanf("%d",&n),n;)
        {
            Input();
            Solve();
            Print();
            putchar('\n');
        }
        return 0;
    }
  • 相关阅读:
    MSP430:管脚的第二功能选择
    MSP430 WDT
    MSP430 G2553 Timer 中断总结
    Timer A UP mode 中断
    AD10 库下载地址
    mysql的视图,事务,索引,外键
    mariadb主从配置
    DNS服务搭建
    数据库的连接查询
    数据库设计及ER模型
  • 原文地址:https://www.cnblogs.com/xchaos/p/2484751.html
Copyright © 2011-2022 走看看