一、如此编码
根据题意模拟即可
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long ll;
#define endl "\n"
int n, m;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
vector<ll> a(n + 1), c(n + 1), b(n + 1);
c[0] = 1;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) c[i] = c[i - 1] * a[i];
ll sum = 0;
for(int i = 1; i <= n; i++) {
b[i] = (m % c[i] - sum) / c[i -1];
sum += c[i - 1] * b[i];
}
for(int i = 1; i <= n; i++) {
cout << b[i] << " ";
}
cout << endl;
return 0;
}
二、如此包邮
1、动态规划
通过分析可知数据最大
n
≤
30
n \leq 30
n≤30,每本书最大价格
a
≤
1
0
4
a \leq10^4
a≤104,所有书的最大总价格不会超过
3
×
1
0
5
3 \times 10^5
3×105,所以可以通过类似01背包,动态规划求解能被装满的背包容量。
设
d
p
[
x
]
=
0
dp[x] = 0
dp[x]=0表示容量为x不能被装满,
d
p
[
x
]
=
1
dp[x] = 1
dp[x]=1表示能被装满。当遍历到价格为
a
a
a的书时,递推方程为:
d
p
[
x
]
=
d
p
[
x
−
a
]
∣
d
p
[
x
]
dp[x] = dp[x - a] \mid dp[x]
dp[x]=dp[x−a]∣dp[x]。
时间复杂度
O
(
n
∑
a
i
)
O(n\sum a_i)
O(n∑ai)。
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long ll;
#define endl "\n"
int n, m, x;
int main() {
cin >> n >> x;
vector<int> a(n);
int sum = 0;
for(int i = 1 ; i <= n; i++) cin >> a[i], sum += a[i];
vector<int> dp(sum + 1);
dp[0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = sum; j >= a[i]; j--) {
dp[j] = dp[j - a[i]] | dp[j];
}
}
int ans = sum;
for(int i = x; i <= sum; i++) {
if(dp[i]) {
cout << i << endl;
return 0;
}
}
return 0;
}
2、折半枚举
将书本分成两半,先处理第一部分书本所能组合出来的价格,并进行排序,在枚举第二部分组合的价格。假设此时价格为 n u m num num, 只需要二分查找大于等于 x − n u m x - num x−num的最小价格,令 m = n / 2 m = n / 2 m=n/2,时间复杂度 O ( m ⋅ 2 m ) O(m \cdot2^{m}) O(m⋅2m)。
#include<bits/stdc++.h>
using namespace std;
int n, x, num1, num2;
int ans = INT_MAX;
vector<int> nums, a1, a2;
void dfs1(int i, int num, int sum) {
nums.push_back(sum);
if (i >= num) return;
dfs1(i + 1, num, sum + a1[i]);
dfs1(i + 1, num, sum);
}
void dfs2(int i, int num, int sum) {
if(sum >= x) ans = min(ans, sum);
if (sum > x) return;
int loc = lower_bound(nums.begin(), nums.end(), x - sum) - nums.begin();
if (loc < nums.size()) ans = min(ans, sum + nums[loc]);
if (i >= num) return;
dfs2(i + 1, num, sum + a2[i]);
dfs2(i + 1, num, sum);
}
void sol() {
cin >> n >> x;
num1 = n >> 1;
num2 = n - num1;
a1.assign(num1, 0), a2.assign(num2, 0);
for (int i = 0; i < num1; i++) cin >> a1[i];
for (int i = 0; i < num2; i++) cin >> a2[i];
nums.push_back(0);
dfs1(0, num1, 0);
sort(nums.begin(), nums.end());
dfs2(0, num2, 0);
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
sol();
return 0;
}
三、防疫大数据
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
set<int> ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
map<int, set<int> > mp;
map<int, set<vector<int>>> mp1;
for (int day = 0; day < n; day++) {
int r, p;
cin >> r >> p;
for (int i = 0; i < r; i++) {
int area;
cin >> area;
for (int j = day; j <= day + 6; j++) {
mp[j].insert(area);
}
}
ans.clear();
for (int i = 0; i < p; i++) {
int d, u, ar;
cin >> d >> u >> ar;
mp1[day].insert({ d, u, ar });
}
for (int i = day - 6; i <= day; i++) {
for (auto& x : mp1[i]) {
if (x[0] > day - 7 && x[0] <= day) {
bool is = true;
for (int j = x[0]; j <= day; j++) {
if (mp[j].find(x[2]) == mp[j].end()) {
is = false;
break;
}
}
if (is) ans.insert(x[1]);
}
}
}
cout << day << " ";
for (auto& x : ans) cout << x << " ";
cout << endl;
}
return 0;
}