cf题解--E. Optimal Slots

https://codeforces.com/group/5yyKg9gx7m/contest/275848/problem/E

E. Optimal Slots

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
inputCopy
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
outputCopy
1 4 5
3 5 2 10
6 10 16
13 13
19 7 2 28

 题目描述;

在n个数中选,使他们的和尽可能靠近T。打印出选择的数。如果存在多个方案,输出最先出现的方案,最后再打印一下和。

分析:

属于简单的01背包最大值问题。T为总花费,a[i]为价值。关键是打印路径。注意要输出最先出现的方案。同样这有一个模板。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<deque>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1e4+6;
int a[maxn];
int dp[maxn];
int T,n;
bool path[maxn][maxn];
void init()
{
    memset(dp,0,sizeof dp);
    memset(path,0,sizeof path);
}
void solve()
{
    //与从后面的印的方法相反 
    for(int i=n-1;i>=0;i--)
    {
        for(int j=T;j>=a[i];j--)
        {
            //需要加等于号,不加出现的方案可能不是最先出现的 
            if(dp[j]<=dp[j-a[i]]+a[i])
            {
                dp[j]=dp[j-a[i]]+a[i];
                path[i][j]=1;
            }
        }
    }
    int j=T;
    //从最先出现的开始,i:1~n-1; 
    for(int i=0;i<n;i++)
    {
        if(path[i][j])
        {
            printf("%d ",a[i]);
            j-=a[i];
        }
    }
    printf("%d\n",T-j);
}
int main()
{
    while(1)
    {
        init();
        cin>>T;
        if(T==0) break;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        solve();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/studyshare777/p/12687991.html