华为OD机试 代表团坐车
题目
某组织举行会议,来了多个代表团同时到达,接待处只有一辆汽车可以同时接待多个代表团,为了提高车辆利用率,请帮接待员计算可以坐满车的接待方案输出方案数量。
约束
1.一个团只能上一辆车,并且代表团人数(代表团数量小于30,每个代表团人数小于30)小于汽车容量(汽车容量小于100)
2.需要将车辆坐满
输入描述
第一行 代表团人数,英文逗号隔开,代表团数量小于30,每个代表团人数小于30第二行 汽车载客量,汽车容量小于100
输出描述
坐满汽车的方案数量
如果无解输出0
示例1:
输入
5,4,2,3,2,4,9
10
输出
4
说明
以下几种方式都可以坐满车,[2,3,5]、[2,4,4]、[2,3,5]、[2,4,4]
动态规划
dp[i][j]的意义:i代表可以选取value数组中0-i编号的元素;j代表客车容纳人数;dpij的值代表i,j限定条件下共有几种方法。
#include <bits/stdc++.h> using namespace std; int main() { vector<int>value; int tmp; while (cin >> tmp) { value.push_back(tmp); if (cin.get() == '\n') break; } sort(value.begin(),value.end()); int v; cin >> v; vector<vector<int>>dp(value.size(),vector<int>(v+1,0)); for (int i = 0; i < value.size(); i++) { dp[i][0] = 1; }//初始化,第一列初始化为1,原因:空间为0时,不论可选元素范围是多少,只有一种方案-不选取任何元素。 dp[0][value[0]] = 1;//初始化 for (int i = 1; i < value.size(); i++) { for (int j = 0; j < v + 1; j++) { if (j - value[i] >= 0) dp[i][j] = dp[i - 1][j] + dp[i - 1][j - value[i]]; else dp[i][j] = dp[i - 1][j]; } } cout << dp[value.size()-1][v]; }
改进:滚动数组降低空间复杂度,注意赋初值和遍历顺序。
#include <bits/stdc++.h> using namespace std; int main() { vector<int>value; int tmp; while (cin >> tmp) { value.push_back(tmp); if (cin.get() == '\n') break; } sort(value.begin(), value.end()); int v; cin >> v; vector<int>dp(v + 1, 0); dp[0] = 1; for (int i = 0; i < value.size(); i++) { for (int j=v; j >=0; j--) { if(j>=value[i]) dp[j] = dp[j] + dp[j - value[i]]; } } cout << dp[v]; }