T1: Conjugation

给定长为 N 的广义单调减小序列 A1,A2,,AN
如图所示,从顶部开始的第 i 行有 Ai 个正方形。

image

对于 j=1,2,,A1,求从左起第 j 列有多少个方格。

限制:

  • 1N105
  • 1Ai105
  • A1A2AN

算法分析

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
reverse(a.begin(), a.end());
for (int i = 1; i <= a.back(); ++i) {
cout << a.end() - lower_bound(a.begin(), a.end(), i) << ' ';
}
return 0;
}

T2:Shio Ramen

太郎是个挑剔的吃货,而二郎是个贪吃鬼。
二郎的桌子上有 N 碗盐味拉面。给这些盐味拉面分别编号为 1,2,,N
对于每个 i,第 i 碗盐味拉面的咸度为 si,口味浓度为 ai 。二郎和太郎一样,喜欢吃盐味拉面,二郎希望吃的盐味拉面味道越浓越好。
二郎很大胆,并不在乎他的盐拉面中的盐味有多浓。
但是,如果二郎吃的总盐味超过 I 就会生病。
作为二郎的朋友,你可以告诉他吃哪些盐味拉面不会生病,并让总的味道浓度达到最大。

限制:

  • 1N,I1000
  • 1si,ai1000

算法分析

01背包

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
inline void chmax(int& x, int y) { if (x < y) x = y; }
int main() {
int n, I;
cin >> n >> I;
vector<int> s(n), a(n);
rep(i, n) cin >> s[i] >> a[i];
vector<int> dp(I+1);
rep(i, n) {
for (int j = I-s[i]; j >= 0; --j) {
chmax(dp[j+s[i]], dp[j]+a[i]);
}
}
cout << dp[I] << '\n';
return 0;
}