UVA10261 Ferry Loading【DP】

Before bridges were common, ferries were used to transport cars across rivers. River ferries, unlike their larger cousins, run on a guide line and are powered by the river’s current. Two lanes of cars drive onto the ferry from one end, the ferry crosses the river, and the cars exit from the other end of the ferry.
    The cars waiting to board the ferry form a single queue, and the operator directs each car in turn to drive onto the port (left) or starboard (right) lane of the ferry so as to balance the load. Each car in the queue has a different length, which the operator estimates by inspecting the queue. Based on this inspection, the operator decides which side of the ferry each car should board, and boards as many cars as possible from the queue, subject to the length limit of the ferry. Your job is to write a program that will tell the operator which car to load on which side so as to maximize the number of cars loaded.
Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
    The first line of input contains a single integer between 1 and 100: the length of the ferry (in metres). For each car in the queue there is an additional line of input specifying the length of the car (in cm, an integer between 100 and 3000 inclusive). A final line of input contains the integer 0. The cars must be loaded in order, subject to the constraint that the total length of cars on either side does not exceed the length of the ferry. Subject to this constraint as many cars should be loaded as possible, starting with the first car in the queue and loading cars in order until no more can be loaded.
Output
For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
    The first line of outuput should give the number of cars that can be loaded onto the ferry. For each car that can be loaded onto the ferry, in the order the cars appear in the input, output a line containing ‘port’ if the car is to be directed to the port side and ‘starboard’ if the car is to be directed to the starboard side. If several arrangements of the cars meet the criteria above, any one will do.
Sample Input
1

50
2500
3000
1000
1000
1500
700
800
0
Sample Output
6
port
starboard
starboard
starboard
port
port

问题链接UVA10261 Ferry Loading
问题简述:(略)
问题分析:动态规划问题,不解释。
程序说明:测试数据有毒?
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA10261 Ferry Loading */

#include <bits/stdc++.h>

using namespace std;

const int N = 2000 + 1;
const int M = 10000 + 1;
int a[N], sum[N], dp[N][M], pre[N][M], where[N];

int main()
{
    int t, len, n;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &len);
        len *= 100;

        sum[0] = 0;
        n = 1;
        while (~scanf("%d", &a[n]) && a[n]) {
            sum[n] = sum[n - 1] + a[n];
            n++;
        }

        n--;
        memset(dp, 0, sizeof dp);
        dp[0][0] = 1;
        int maxcar = 0, maxlen;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= len; j++) {
                if (j - a[i] >= 0 && dp[i - 1][j - a[i]]) {
                    dp[i][j] = 1;
                    pre[i][j] = 0;  // left
                }
                if (sum[i] - j <= len && dp[i- 1][j]) {
                    dp[i][j] = 1;
                    pre[i][j] = 1;  // right
                }
                if (dp[i][j])
                    maxcar = i, maxlen = j;
            }
            if (maxcar != i) break;
        }

        int i = maxcar, j = maxlen;
        while (i) {
            where[i] = pre[i][j];
            if (pre[i][j] == 0) j -= a[i];
            i--;
        }

        printf("%d\n", maxcar);
        for (int i = 1; i <= maxcar; i++)
            puts(where[i] ? "starboard" : "port");
        if (t) putchar('\n');
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值