D. Smithing Skill 和 D. Grid Puzzle的题解
D. Smithing Skill:
https://codeforces.com/problemset/problem/1989/D
思路:
https://blog.csdn.net/weixin_73936404/article/details/140045020
(看这位的博客吧,这个本人第一次写卡住了, 题解就当复盘了)
贪心:优先消耗值小的(花费和返回的差值)且门槛小的。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int xmmm=1e6+10;
const int mod=1e9+7;
int a[xmmm];
int c[xmmm];
int dp[xmmm];
void solve(){
int n, m;cin>>n>>m;
int mm=0;
for(int i=1;i<=n;i++){
cin>>a[i];
mm=max(mm, a[i]);
}
for(int i=0;i<=mm;i++)c[i]=1e9;
for(int i=1;i<=n;i++){
int b;cin>>b;
c[a[i]]=min(c[a[i]], a[i]-b);
}
//cout<<mm<<' ';
for(int i=1;i<=mm;i++){
c[i]=min(c[i], c[i-1]);//重点是这一步, 更新当门槛为i时最小消耗为c[i],
if(c[i]==1e9)continue;//当前材料量为i时,锻造不了任何金属
dp[i]=max(dp[i], dp[i-c[i]]+1);
}
int ans=0;
for(int i=1;i<=m;i++){
int t;cin>>t;
if(t>mm){
int an=(t-mm)/c[mm]+1;
ans+=an;
t-=c[mm]*an;
}
ans+=dp[t];
}
cout<<ans*2<<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;//cin>>T;
T=1;
while(T--){
solve();
}
return 0;
}
D. Grid Puzzle
https://codeforces.com/contest/1990/problem/D
思路:
操作1可以看作操作2,就像本来可以消除1排, 但是这一排只有<=2个黑块, 所以就给了优惠,可以送两个下面的黑块。
所以所有操作优先操作2, 如果满足优惠,就用b数组维护;不满足直接++,就好了。
如果当前排享受了优惠,但是还要涂黑>=3块, 可以看作没有享受上一排的优惠,只是使用了操作2, 只要ans++即可。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int xmmm=2e5+10;
const int mod=1e9+7;
int a[xmmm];
struct p{
int l=0, r=0;
}b[xmmm];
void solve(){
int n;cin>>n;
for(int i=0;i<=n+1;i++)b[i].l=b[i].r=0;//初始化
for(int i=1;i<=n;i++)cin>>a[i];
int ans=0;
for(int i=1;i<=n;i++){
if((b[i].l==1&&b[i].r>=a[i])||a[i]==0)continue;//不用再涂黑
ans++;
//接下来有三种可以使用优惠的三种情况
if(b[i].l==0&&b[i].r==0&&a[i]<=2){
b[i+1].l=1, b[i+1].r=2;
}
else if(b[i].l==1&&a[i]<=4){
b[i+1].l=b[i].r+1,b[i+1].r=b[i].r+2;
}
else if(b[i].r>=a[i]){
if(b[i].l<=3)b[i+1].l=1, b[i+1].r=2;
}
}
cout<<ans<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--){
solve();
}
return 0;
}