CS 300 Switch the Lights 观察+前缀差分

来源:互联网 发布:送q币的软件 编辑:程序博客网 时间:2024/05/29 15:41
题意:n个灯泡,01表示是否点亮.n个开关,第i个开关反转[i,r[i]]个灯泡,花费c[i].
n<=1e5,c[i]<=1e9问将灯泡全部熄灭需要的最小花费?


每个开关最多使用一次.注意第i个开关 变化的左端点为i.假设序列最左边第一个为1的位置为x
此时开关j>x 无法熄灭x.开关j<x ? 若使用k<j<x的开关 则前面为0的变为1.会陷入死循环.




所以每次转动编号为:当前最左边第一个1位置的开关.
转动后如何找到下一个为1的位置?

记录每个点的反转次数,前缀差分记录一下即可.

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+5;int n,r[N],c[N],a[N];int f[N];char s[N];int main(){    cin>>n;    scanf("%s",s+1);    for(int i=1;i<=n;i++)        a[i]=s[i]-'0',scanf("%d",&r[i]);    for(int i=1;i<=n;i++)        scanf("%d",&c[i]);    ll ans=0;    for(int i=1;i<=n;i++)    {        f[i]+=f[i-1];        int num=0;        if(f[i]%2)            num++;        if(a[i]+num==1)        {            ans+=c[i];            f[i]++;            f[r[i]+1]--;        }    }    cout<<ans<<endl;    return 0;}


 
原创粉丝点击