CodeForces - Optimal Slots(01背包&记录路径)

题目链接:http://codeforces.com/gym/102219/problem/E
Time limit per test 2.0 s Memory limit per test 256 MB

Description

The main hall of your residency is open for use by the local community and public. Since it was built on public donations, there is no charge of using it. Every weekend particularly on public holidays there are up to 50 reservations to use it for multiple events with different durations.

You have been assigned by the residents to develop a program in choosing events to get most out of allocation time per weekend and have as short unused time as possible. Program should find the event(s) which fill(s) the allocation time best and print it in the same sequence as appears in the reservation list.

Input

Each test case consist of a single line.

The line starts with two integer T and N which is the time allocated for the hall to be used in the particular weekend and the number of events. The next T integer are the durations of the events (as appear in the reservation list). For example from the first line in sample data: T=5 hours, N, number of events =5, first event lasts for 1 hour, second is 2 hours, third is 3 hours, fourth is 4 hours, and the last one is 5 hours.

The input process will be terminated by a line containing 0.

Output

For each line of input value, in a single line, first, output a list of integers which are the selected events duration and another integer which is the sum of the selected events duration.

If there are multiple possible list of events, events that appear earlier in the list takes priority.

Example

input

5 5 1 2 3 4 5
10 9 11 9 3 5 8 4 9 3 2
16 8 12 6 11 11 13 1 10 7
13 5 10 12 2 13 10
28 14 18 19 26 15 18 24 7 21 14 25 2 12 9 6
0

output

1 4 5
3 5 2 10
6 10 16
13 13
19 7 2 28

Problem solving report:

Description: 跟01背包有点像,给定t和序列,从头开始选一些数,问如何安排使得容量尽量装满,输出选了哪些数。如果有多种,输出每种数字尽可能靠前的。
Problem solving: 01背包加路径记录,用path[i][j]表示到第i个数时容量为j时的选择(0不选,1选),最后把路径输出就行了。

Accepted Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 55;
const int MAXM = 105;
int dp[MAXN], w[MAXN];
bool path[MAXN][MAXN];
int main() {
    int t, n, m;
    while (scanf("%d", &m), m) {
        scanf("%d", &n);
        memset(dp, 0, sizeof(dp));
        memset(path, 0, sizeof(path));
        for (int i = 0; i < n; i++)
            scanf("%d", w + i);
        for (int i = n - 1; ~i; i--) {
            for (int j = m; j >= w[i]; j--) {
                if (dp[j] <= dp[j - w[i]] + w[i]) {
                    dp[j] = dp[j - w[i]] + w[i];
                    path[i][j] = 1;
                }
            }
        }
        for (int i = 0, j = m; i < n; i++) {
            if (path[i][j]) {
                printf("%d ", w[i]);
                j -= w[i];
            }
        }
        printf("%d\n", dp[m]);
    }
    return 0;
}
全部评论

相关推荐

程序员花海:实习和校招简历正确格式应该是教育背景+实习+项目经历+个人评价 其中项目经历注意要体现业务 实习经历里面的业务更是要自圆其说 简历模板尽可能保持干净整洁 不要太花哨的
点赞 评论 收藏
分享
11-03 13:18
门头沟学院 Java
包行:平时怎么刷算法题的哇,字节的手撕听说都很难
字节跳动工作体验
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务