题意:
给定n个房间 要给每个房间连上网络 第i个房间连上网络的花费为i 有些房间可以装上路由器 如果装上路由器 那么左边k个和右边k个都可以被装上网络 且装路由器的费用也为i
问最少花费使得所有的房间装上网络
dp 用单调队列优化一下即可 :
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// const int N=2e6+10; int n,m,l,r,st[N],k; char s[N]; ll dp[N]; int main() { scanf("%d%d",&n,&k); scanf("%s",s+1); l=r=1;st[1]=0; rep(i,1,n+k) { dp[i]=dp[i-1]+i; if(i>k&&s[i-k]=='1') { dp[i]=min(dp[i],dp[st[l]]+i-k); } if(st[l]<i-2*k)l++; while(l<=r&&dp[st[r]]>=dp[i])r--; st[++r]=i; } ll ans=1e18; rep(i,n,n+k)ans=min(ans,dp[i]); cout<<ans; return 0; }