Atcoder(ABC431)A-D
A - Robot Balance
思路:
非常的简单,就是输出头和身体的重量差
代码:
void solve()
{int n,m;cin>>n>>m;cout<<max(0,n-m)<<endl;
}
B - Robot Weight
思路:
偶数加,奇数减,下标对应,随时变化状态
代码:
void solve()
{int x,n;cin>>x>>n;vector<int>a(n+1,0);vector<bool>st(n+1,false);for(int i=1;i<=n;i++)cin>>a[i];int q;cin>>q;while(q--){int m;cin>>m;if(!st[m]){x+=a[m];st[m]=true;}else {x-=a[m];st[m]=false;}cout<<x<<endl;}
}
C - Robot Factory
思路:
头的重量和身体重量,符合条件就匹配,至少要K个。
双循环过于简单,这里考虑双指针来优化。
我们可以发现顺序不重要,我们可以直接排序,从小到大去匹配,如果满足就都++,不满足我们让身体的指针++,当身体小于头时,我们按升序排,看后面的身体能不能匹配头。
代码:
void solve()
{int n,m,k;cin>>n>>m>>k;vector<int>a(n),b(m);for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<m;i++)cin>>b[i];sort(a.begin(),a.end());sort(b.begin(),b.end());int l=0,r=0;int cnt=0;while(l<n&&r<m){if(a[l]<=b[r])cnt++,l++,r++;else r++;}if(cnt>=k)cout<<"Yes"<<endl;else cout<<"No"<<endl;}
D - Robot Customize
思路:
我们先把条件化简一下:
WH <= WB(头的总重量小于等于身体的总重量)
要计算出最大的幸福值,我们可以贪心的选择把每一个零件都放到头部,然后在加上部分( H - B )的幸福值,即:
ans=∑i=0nH+∑i=0n(H−B)ans=\sum_{i=0}^{n}H+\sum_{i=0}^{n}(H-B)ans=i=0∑nH+i=0∑n(H−B)
结合上述条件,我们还可以发现一个结论:
已知:
H+B=WH + B=WH+B=W
H<=BH<=B H<=B
代入:
H<=W−BH <= W -BH<=W−B
H<=W2H <= \frac {W}{2} H<=2W
所以 头部总重量不能超过总重量的一半。
我们就可以把问题转化一下:
我们要选择一些零件放在头部,使得:
它们的总重量 ≤ 总重量的一半
它们的 (H-B) 之和尽量大
这就转化为了一个01背包
代码:
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;typedef long long ll;void solve()
{int n;cin >> n;ll total = 0;vector<pair<int, int>> a; // (w, h-b)ll base = 0;for (int i = 0; i < n; i++) {int w, h, b;cin >> w >> h >> b;total += w;a.push_back({w, h - b});base += b;}ll k = total / 2;vector<ll> dp(k + 1, -1e18);dp[0] = 0;for (auto [w, c] : a) {for (int i = k; i >= w; i--) {if (dp[i - w] != -1e18) {dp[i] = max(dp[i], dp[i - w] + c);}}}ll maxn = 0;for (int i = 0; i <= k; i++) {maxn = max(maxn, dp[i]);}cout << base + maxn << endl;
}int main()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;// cin >> t;while(t--)solve();return 0;
}
