Optimal Slots
在这里,要单独把题意拉出来,因为题目中确实说的好隐蔽。
给出一个T指的是周末的时间,周末只有两天,算成小时也就是只有48个小时,这是隐蔽一,第二个是N(N<=50)有N个可以用的时间长度,要使得所有使用的时间长度之和小于等于T且是最大的,问合计。并且,如果有多个答案的话,这题还不是spj(不然的话岂不是01背包板子题?)
If there are multiple possible list of events, events that appear earlier in the list takes priority.
输出的是最小字典序的,这里的字典序指的是按照输入的顺序来确定的ID,也就是第一个输入的为1,第二个输入的字典序为2,以此类推,我们要字典序最小的。
那么,题意大致清楚了,接下去就是过程了,很显然50*48,挺小的,然后就想到,既然是继承,那么我们完全可以还是去推这个01背包,只是为了满足字典序最小的,那么我们把原来从1~N的推导过程变成先放入第N个再放入第N-1个,这样从后往前塞满这个背包,那么,如果说,目前这个状态是有的,并且呢,减掉这个时间长度,是可以到达下一个状态的话,我们可以使用这样的时间长度。
具体看一下DP所表达的内容:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 55;
int T, N, a[maxN], dp[maxN][maxN];
int main()
{
while(scanf("%d", &T) && T)
{
scanf("%d", &N);
for(int i=1; i<=N; i++) scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
for(int i=N; i>=1; i--)
{
for(int j=0; j<=T; j++) dp[i][j] = dp[i + 1][j];
for(int j=T; j>=a[i]; j--)
{
dp[i][j] = max(dp[i][j], dp[i + 1][j - a[i]] + a[i]);
}
}
int ans = dp[1][T], id = 1;
int x = ans;
while(x && id <= N)
{
if(x >= a[id] && dp[id][x] == dp[id + 1][x - a[id]] + a[id])
{
printf("%d ", a[id]);
x -= a[id];
}
id ++;
}
printf("%d\n", ans);
}
return 0;
}