比较重要的例题

滑动窗口+dp

很有意思找最小花费

用双向队列维护,仔细看看想想

每一次跑都从头跑,然后去排掉大的花销

dp思想

Problem - E - Codeforces

#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
//#define double long double
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5,M=1e9+7;
const int INF = 0x3f3f3f3f;
const int mod=998244353;
typedef pair<int,int> PII;

int a[105][N];
void solve()
{
    int n,m,k,d;
    cin>>n>>m>>k>>d;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    vector<int> sum;
    for(int i=1;i<=n;i++)
    {
        deque<int> q;
        int dp[m+2];
        dp[1]=1;
        q.push_back(1);
        for(int j=2;j<=m;j++)
        {
            while (!q.empty() && j-q.front()-1>d) q.pop_front();
            dp[j]=dp[q.front()]+a[i][j]+1;
            while (!q.empty() && dp[q.back()]>dp[j]) {
                q.pop_back();
            }
            q.push_back(j);
        }
        sum.push_back(dp[m]);
    }
    int pp[N];
    pp[0]=sum[0];
    for(int i=1;i<sum.size();i++)
    {
        pp[i]=pp[i-1]+sum[i];
    }
    int ans=pp[k-1];
    for(int i=k;i<sum.size();i++)
    {
        ans=min(ans,pp[i]-pp[i-k]);
    }
    cout<<ans<<endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

 优先队列重载函数写法

struct G
{
    int s,w;
    int id;
}a[N];
class cmp{
public:
    bool operator() (G& x,G& y)
    {
        if(x.s==y.s) return x.id>y.id;
        return x.s<y.s;
    }
};
priority_queue<G,vector<G>,cmp> mp;

结构体内置排序函数写法

struct G{
    int s,w,id;
    bool operator<(const G &t)const {
        if(t.s==s) return id<t.id;
        return s>t.s;
    }// 直接在结构体里排序方法,外面就不需要写cmp了,直接sort排序即可
};

 

posted @ 2024-03-15 00:48  whatdo+  阅读(4)  评论(0编辑  收藏  举报