题目
背景
Freda和rainbow饲养了NNN只小猫,这天,小猫们要去爬山。经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。
描述
Freda和rainbow只好花钱让它们坐索道下山。索道上的缆车最大承重量为WWW,而N只小猫的重量分别是C1C1C1、C2C2C2………………CNCNCN。当然,每辆缆车上的小猫的重量之和不能超过WWW。每租用一辆缆车,Freda和rainbow就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?
输入格式
第一行包含两个用空格隔开的整数,N和WN和WN和W。
接下来NNN行每行一个整数,其中第i+1i+1i+1行的整数表示第i只小猫的重量CiCiCi。
输出格式
输出一个整数,最少需要多少美元,也就是最少需要多少辆缆车。
样例输入
555 199619961996
111
222
199419941994
121212
292929
样例输出
222
数据范围与约定
对于100%的数据,1<=N<=181<=N<=181<=N<=18,1<=Ci<=W<=1081<=Ci<=W<=10^81<=Ci<=W<=108。
题解
dfsdfsdfs例题
dfs(now,cnt)dfs(now,cnt)dfs(now,cnt)表示当前搜索到了第nownownow只猫,且分配了cntcntcnt条电缆。
然后开一个cab[i]cab[i]cab[i]记录当前第iii条电缆的载重,搜索即可。
code
/*
my ideas
-----------------------------------------------
一、
dfs
排序
贪心
dfs(x, y)表示当前 x重量 y只猫
----------------------------------------------
二、
dfs(x, y, z) x, y 同理, z 为当前第几条电缆
边界条件 y == x
结果 ans = min(ans, z)
----------------------------------------------
三、
dfs(now, x, y, z) x, y, z 同理
now 表示当前为第几只猫
----------------------------------------------
四、
for循环搜索
---------------------------------------------
~~~~
/*
void dfs(int now, LL x, int y, int z) {
if (y == n) ans = max(ans, z);
for (int i = now + 1; i <= n; ++i) {
if (i > n) continue;
if (x + c[i] <= w)
dfs(i, x + c[i], y + 1, z);
else
dfs(i, c[i], y + 1, z + 1);
}
}
sort(c + 1, c + n + 1);
dfs(1, c[1], 1, 1);
~~~~
↑↑↑↑↑↑↑↑↑↑↑↑
18分代码
--------------------------------------------
五、
以下思路来自算法进阶
dfs(now, cnt) 处理第now只小猫的分配过程, 并且已经用了cnt个缆车。
对于这cnt个缆车的搭载量我们开一个全局数组cab来记录。
*/
#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <bitset>
#define clean(x, y) memset(x, y, sizeof(x))
const int maxn = 100;
const int inf = 0x3f3f3f3f;
typedef long long LL;
using namespace std;
template <typename T>
inline void read(T &s) {
s = 0;
T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
s *= w;
}
int n;
int ans;
LL w;
LL cab[maxn];
LL c[maxn];
/*
void dfs(int now, LL x, int y, int z) {
if (y == n) ans = max(ans, z);
for (int i = now + 1; i <= n; ++i) {
if (i > n) continue;
if (x + c[i] <= w)
dfs(i, x + c[i], y + 1, z);
else
dfs(i, c[i], y + 1, z + 1);
}
}
*/
inline bool cmp(int a, int b) { return a > b; }
void dfs(int now, int cnt) {
if (cnt >= ans) return;
if (now > n) {
ans = min(ans, cnt);
return ;
}
for (int i = 1; i <= cnt; ++i) {
if (cab[i] + c[now] <= w) {
cab[i] += c[now];
dfs(now + 1, cnt);
cab[i] -= c[now];
}
}
cab[cnt + 1] = c[now];
dfs(now + 1, cnt + 1);
cab[cnt + 1] = 0;
}
int main() {
ans = -inf;
read(n), read(w);
for (int i = 1; i <= n; ++i)
read(c[i]);
ans = n;
sort(c + 1, c + n + 1, cmp);
dfs(1, 0);
printf("%d\n", ans);
return 0;
}