POJ 3390 Print Words in Lines(DP)

Print Words in Lines

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1624 Accepted: 864

Description

We have a paragraph of text to print. A text is a sequence of words and each word consists of characters. When we print a text, we print the words from the text one at a time, according to the order the words appear
in the text. The words are printed in lines, and we can print at most M characters in a line. If there is space available, we could print more than one word in a line. However, when we print more than one word in a line, we need to place exactly one
space character between two adjacent words in a line. For example, when we are given a text like the following:

This is a text of fourteen words and the longest word has ten characters

Now we can print this text into lines of no more than 20 characters as the following.

This is

a text of

fourteen words

and the longest

word

has ten characters

However, when you print less than 20 characters in a line, you need to pay a penalty, which is equal to the square of the difference between 20 and the actual number of characters you printed in that line. For example
in the first line we actually printed seven characters so the penalty is (20 ? 7)2 = 169. The total penalty is the sum of all penalties from all lines. Given the text and the number of maximum number of characters allowed in a line, compute the
minimum penalty to print the text.

Input

The first line of the input is the number of test cases (C). The first line of a test case is the maximum number of characters allowed in a line (M). The second line of a test case is the number of
words in the text (N). The following N lines are the length (in character) of each word in the text. It is guaranteed that no word will have more than M characters, N is at most 10000, and M is at most 100.

Output

The output has C lines. Each line has the minimum penalty one needs to pay in order to print the text in that test case.

Sample Input

2
20
14
4
2
1
4
2
8
5
3
3
7
4
3
3
10
30
14
4
2
1
4
2
8
5
3
3
7
4
3
3
10

Sample Output

33
146

Source

Kaohsiung 2006

题意  把n个单词排版   每行最多m个字符 不同单词间有空格 每行最后一个单词后没空格   空格占一个字符   当一行的字符数与m的差为t时 就会扣t*t分  求最少扣分

令a[i]表示第i个单词的长度   s[i]表示从第一个单词到第i个单词单词长度和d[i]表示前i个单词排版后最少扣的分

则t=m-(s[i] - s[j] + i - j - 1)表示把从第j+1个单词到第i个单词放在一行时这行的字符长度与m的差

那么当t>=0时  有转移方程 d[i]=min(d[i],d[j]+t*t) ;

有了方程程序就好写了:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10005;
int s[N], d[N], a[N], t, cas, m, n;
int main()
{
    scanf ("%d", &cas);
    while (cas--)
    {
        scanf ("%d%d", &m, &n);
        for (int i = 1; i <= n; ++i)
        {
            scanf ("%d", &a[i]);
            s[i] = s[i - 1] + a[i];
        }
        memset (d, 0x3f, sizeof (d)); d[0] = 0;
        for (int i = 1; i <= n; ++i)
            for (int j = i - 1; j >= 0; --j)
            {
                t = m - (s[i] - s[j] + i - j - 1);
                if (t >= 0)  d[i] = min (d[i], d[j] + t * t);
                else break;
            }
        printf ("%d\n", d[n]);
    }
}

POJ 3390 Print Words in Lines(DP)

时间: 2024-10-13 09:28:24

POJ 3390 Print Words in Lines(DP)的相关文章

poj 3390 Print Words in Lines 动态规划

题意: 给n个单词的长度和每行最多能放的字符数m,每行产生的值为(m-x)^2,x是该行的字符数(包括单词之间的空格),求把所有单词放完产生的值的最小和. 分析: 动态规划很重要的就是状态的定义,在由子问题向父问题推进的过程中,定义的状态要能对之前的所有情况进行总结,比如背包问题中dp[i][v]中的v,不管之前1~i-1个物品如何取舍,他们的总重量肯定在0~v之中,故每步能把指数级的问题线性化.这题也是,刚考虑第i个单词时,前面所有单词不管怎么放最后一个的结束位置肯定在1~m之间,故定义dp[

POJ 3071 Football (动态规划-概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2768   Accepted: 1412 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

POJ 1651 Multiplication Puzzle (区间dp)

题目大意:对n个数组成的序列取数,规定最两边不能取,每次取一个a[i],得到 a[l] * a[i] * a[r] 的分数(a[l]是a[i]左边的数,a[r]是a[i]右边的数),并把这个数从序列中移走,求n-2次取数后的得分和的最小值 分析:正着确定状态不好做,不如反着来,设dp[l][r]为向区间[l, r]中填满数所得到分数和的最小值,考虑最近一次填数的位置,不难得出: dp[l][r] = fmin(dp[l][m] + dp[m][r] + a[l] * a[m] * a[r]) (

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3071 Football(简单 概率DP)

Football 原文链接:http://blog.csdn.net/xuechelingxiao/article/details/38520105 大意:2^n 个球队进行单场淘汰赛,每两只球队之间比赛会有胜负的概率,问最后谁夺冠的概率最大. 思路:简单的概率DP问题,主要是怎么处理哪两个球队比赛的问题. DP方程为 dp[i][j] = ∑(dp[i-1][j]*dp[i-1][k]*p[j][k]); //dp[i][j]表示第 i 轮的时候,第 j 支队伍赢的概率.. 对于其中位运算,可

POJ 1185 炮兵阵地 状压dp

http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n, m, cnt, size; 7 int a[110], st[70], ct[70]; 8 char str[15]; 9 int f[110][70][70]; 10 void init(

POJ 3132 Sum of Different Primes DP背包

http://poj.org/problem?id=3132 题意: 给定n和k,问用恰好k个不同的质数来表示n的方案数. 分析: n和k都很小.反正就是个背包,选k个物品恰好填满n即可. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 bool dp[1200][15]; 6 int ct[1200][15]; 7 int p[1200]; 8 bool a[1200]; 9 int n, k,

poj 4045 Power Station(初涉树形dp)

http://poj.org/problem?id=4045 大致题意:有n个村庄,求将发电站建在哪一个村庄使得花费最少.这是一个无向无环图.简化一下就是求一个节点使它到其他所有节点的距离和最小. 起初一直在向最短路上靠,但因为节点和边数太大,必定TLE.然后无比强大的啸神随便写了两个dfs就过掉了,简直膜拜.赛后搜了搜题解,发现这是道树形dp.sad,真的要好好刷dp了. 大体思路是将这个无向无环图看做一个树,我们就在这个树上进行动态规划.首先先随便拿一个节点看做根节点(假设节点1),计算出它

POJ 2411 Mondriaan&#39;s Dream( 轮廓线dp )

最普通的轮廓线dp... 复杂度O(nm2min(n, m)) -------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; #define b(x) (1 << (x)) const in