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;
}
 
posted @ 2025-01-09 21:57  devoteeing  阅读(48)  评论(0)    收藏  举报