【利用数据结构进行贪心】

【利用数据结构进行贪心】

用某数据结构进行维护
堆/单调栈/单调队列/...

灵梦的字符串问题【堆】

https://ac.nowcoder.com/acm/contest/106509/C

image

注意一个小细节:
优先选择ans+=的形式
image

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int N=2e5+10;
/*
如何判断当前字符被复制后能使整个数组的字典序变小?
->模拟堆的形式
  从后往前遍历 依次加堆 如果字符相同:弹出 否则判断堆顶是否<当前字符->若小于则说明当前点复制能变小
*/
int n;
ll m;
string s;
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>n>>m;
      cin>>s;
      vector<ll> a(n+1);
      vector<bool> st(n+1);
      for(int i=0;i<n;i++) cin>>a[i];
      string t;
      t+=s.back();
      //注意string也有这些写法!
      for(int i=n-2;i>=0;i--){
            if(!t.empty() && t.back()==s[i]) t.pop_back();
            if(t.size() && t.back()>s[i]) st[i]=1;
            t+=s[i];
      }
      string ans;
      for(int i=0;i<n;i++){
            ans+=s[i];
            if(st[i] && a[i]<=m){ 
                  ans+=s[i];
                  m-=a[i];
            }
      }
      cout<<ans;
      return 0;
}

扫雷 1【单调栈】

https://codeforces.com/gym/105158/attachments
注意读题:一个探测器可以选无数次!!!->马上否定反悔贪心

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
//注意一个地雷可以在一轮买很多次!!!
/*
后面的轮中如果有一个很便宜的探测器,那么我们直接留着钱只买这个就行了,能买多少就买多少
探测器便宜又靠后->【单调栈(单调上升)】
*/
int n;
void solve(){
    cin>>n;
    vector<int> c(n+1,0);
    for(int i=1;i<=n;i++) cin>>c[i];
    //单调栈
    vector<PII> pos;
    for(int i=1;i<=n;i++){
        while(!pos.empty() && pos.back().first>c[i]) pos.pop_back();
        pos.push_back({c[i],i});
    }
    int ans=0,cnt=0;
    int pre=0;
    for(auto [c,i]:pos){
        cnt+=i-pre;
        int cnt1=cnt/c;
        ans+=cnt1;
        cnt-=cnt1*c;
        pre=i;
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--) solve();
    return 0;
}
posted @ 2025-04-05 18:05  White_ink  阅读(6)  评论(0)    收藏  举报