[JOYOI1468] 清理垃圾 - DP

题目限制

时间限制 内存限制 评测方式 题目来源
1000ms 131072KiB 标准比较器 Local

题目背景

聚会结束,留下许多垃圾。
Candy:“好多垃圾啊,飘飘乎居士,我们一起处理垃圾吧!”

题目描述

    Candy家里总共有n个垃圾等待处理,每个垃圾对于Candy和飘飘乎居士处理的时间都是不同的,而且每个垃圾只需要一个人处理。当然,Candy和飘飘乎居士可以同时处理不同的垃圾。记两人中耗费最长时间为最后总时间。Candy希望能够尽快的处理完所有的垃圾,因此,他想要知道处理完这些垃圾最少需要耗费多少时间?

输入格式

第一行一个正整数n,表示一共有n个垃圾需要处理
接下来一个2*n的矩阵。
矩阵第一行第i个数表示candy处理第i个垃圾所需消耗的时间
矩阵第二行第i个数表示飘飘乎居士处理第i个垃圾所需消耗的时间

输出格式

一行,最后耗费的时间

提示

Candy完成垃圾3与垃圾4的清理,耗时为5
飘飘乎居士完成垃圾1 2 5的清理,耗时为4,由于Candy耗费的时间较长,所以记Candy耗费时间为最后总时间,所以最后答案为5。
对于30%的数据 0<n<=30
对于100%的数据 0<n<=1000,Candy和飘飘乎居士处理每个垃圾的时间<=10,对任何一个人处理所有垃圾时间总和<=4000

样例数据

输入样例 #1 输出样例 #1
5

2 4 1 4 5

2 1 3 4 1

5


提交地址 : JOYOI


题解

水水的DP...

我们设f[i][j], 表示第i件事, 小人A用了j分钟, 小人B用的时间:

所以f[i][j] = min(f[i-1][j-a[i]], f[i-1][j] + b[i]) ;

然而...算了算...150mb...爆空间...

发现f[i][j]只和f[i-1][j]有关,所以滚动数组优化直接A掉


Code

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int n;
 8 int a[10001], b[10001];
 9 int f[2][4001];
10 
11 int ans = 1e9;
12 
13 int main()
14 {
15     cin >> n;
16     for (register int i = 1 ; i <= n ; i ++) scanf("%d", &a[i]);
17     for (register int i = 1 ; i <= n ; i ++) scanf("%d", &b[i]);
18     
19     memset(f, 0x3f, sizeof f);
20     f[0][0] = 0;
21     
22     for (register int i = 1 ; i <= n ; i ++)
23     {
24         memset(f[i%2],0x3f,sizeof f[i%2]);
25         for (register int j = 0 ; j <= 4000 ; j ++)
26         {
27             if (j >= a[i]) f[i%2][j] = min(f[i%2][j], f[(i-1)%2][j-a[i]]);
28             f[i%2][j] = min(f[i%2][j], f[(i-1)%2][j] + b[i]);            
29         }
30     }
31     
32     for (register int i = 0 ; i <= 4000 ; i ++)
33     {
34         ans = min(ans, max(f[n%2][i], i));
35     }
36     cout << ans << endl;
37     return 0;
38 }

猜你喜欢

转载自www.cnblogs.com/zZh-Brim/p/9160247.html