Cutting Sticks

Cutting Sticks

时间: 1ms        内存:64M

描述:

You have to cut a wood stick into several pieces. The most affordable company, Analog Cutting Machinery (ACM), charges money according to the length of the stick being cut. Their cutting saw allows them to make only one cut at a time.
It is easy to see that different cutting orders can lead to different prices. For example, consider a stick of length 10 m that has to be cut at 2, 4, and 7 m from one end. There are several choices. One can cut first at 2, then at 4, then at 7. This leads to a price of 10 + 8 + 6 = 24 because the first stick was of 10 m, the resulting stick of 8 m, and the last one of 6 m. Another choice could cut at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 = 20, which is better for us.

Your boss demands that you write a program to find the minimum possible cutting cost for any given stick.

输入:

The input will consist of several input cases. The first line of each test case will contain a positive number l that represents the length of the stick to be cut. You can assume l < 1,000. The next line will contain the number n (n < 50) of cuts to be made. The next line consists of n positive numbers ci ( 0 < ci < l) representing the places where the cuts must be made, given in strictly increasing order. An input case with l = 0 represents the end of input.

输出:

Print the cost of the minimum cost solution to cut each stick in the format shown below.

示例输入:

100
3
25 50 75
10
4
4 5 7 8
0

示例输出:

The minimum cutting is 200.
The minimum cutting is 22.

提示:

参考答案(内存最优[1280]):

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <set>
using namespace std;
#define MAXN 55

int len , m;
int dp[MAXN][MAXN];
int cut[MAXN];


void solve(){
    int i , j , k , p , tmp , min;
    cut[0] = 0 ; cut[m+1] = len;
    memset(dp , 0 , sizeof(dp));
    for(p = 1 ; p <= m+1 ; p++){
        for(i = 0 ; i <= m+1-p ; i++){
            j = i+p ; min = 999999999;
            for(k = i+1 ; k < j ; k++){
                tmp = dp[i][k]+dp[k][j]+cut[j]-cut[i];
                if(tmp < min) min = tmp;
            }
            if(min != 999999999) dp[i][j] = min;
        }
    }
    printf("The minimum cutting is %d.\n" , dp[0][m+1]);
}


int main(){
    //freopen("input.txt" , "r" , stdin);
    while(scanf("%d" , &len) && len){
        scanf("%d" , &m);
        for(int i = 1 ; i <= m ; i++) scanf("%d" , &cut[i]);
        solve();
    }
    return 0;
}

参考答案(时间最优[0]):

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <set>
using namespace std;
#define MAXN 55

int len , m;
int dp[MAXN][MAXN];
int cut[MAXN];


void solve(){
    int i , j , k , p , tmp , min;
    cut[0] = 0 ; cut[m+1] = len;
    memset(dp , 0 , sizeof(dp));
    for(p = 1 ; p <= m+1 ; p++){
        for(i = 0 ; i <= m+1-p ; i++){
            j = i+p ; min = 999999999;
            for(k = i+1 ; k < j ; k++){
                tmp = dp[i][k]+dp[k][j]+cut[j]-cut[i];
                if(tmp < min) min = tmp;
            }
            if(min != 999999999) dp[i][j] = min;
        }
    }
    printf("The minimum cutting is %d.\n" , dp[0][m+1]);
}


int main(){
    //freopen("input.txt" , "r" , stdin);
    while(scanf("%d" , &len) && len){
        scanf("%d" , &m);
        for(int i = 1 ; i <= m ; i++) scanf("%d" , &cut[i]);
        solve();
    }
    return 0;
}

题目和答案均来自于互联网,仅供参考,如有问题请联系管理员修改或删除。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注