这道题我一开始的思考是逐步改变某个位的1、0,结果发现如果这样的话dp爆栈先不说,并且无法写出状态转移的方程,联想到大模型视频生成的算法中有一条就是取消单时间节点的生成,转用整体时间轴的生成,这就启发了我从整体入手,自然地发现了字符串标准串就只有两种情况,1010……和010101……那么就简单了,我只需要将输入字符串同标准字符串进行比较即可

那么问题就剩下如何进行比较了,既要保存位数信息,还要进行比较,如果要用二进制位运算来实现的话,你会发现位数太大了,你无法进行转化(即把字符串转化为二进制数),那么这时候的遍历显得非常的有性价比了,因为时间复杂度也只有O(N)

你又瞪眼出来了,因为对于两种情况,它们的耦合程度(你直觉上感知的)非常高,改某上的10其实就是不改某位上的10,也就是,两个情况改成标准的代价总和是固定的,你试着解决这个问题,发现是非常简单的,因为就是简单的等差数列求和,当然,注意到数据的大小,你要把你一开始的int 改成long long

#include<iostream>
using namespace std;
int main(){
    long long n;
    cin>>n;
    long long cost=0;
    long long sum=((n+1)*n)/2;
    for(int i=1;i<=n;i++){
        int temp;
        cin>>temp;
        if(temp!=(i%2==0)?1:0){//wa
            cost+=i;
        }
    }
    cout<<(cost<=(sum-cost))?cost:(sum-cost);//wa
    return 0;
}

你写完之后,发现了段错误,你在写的时候就觉得不对劲了,三目运算符的细节你并不熟悉,这就导致了操作符的顺序其实是错的

然后,你又发现了,题目input根本就没有n,所以你发现了,你逃不过要输入一次string,然后进行转化

改正的答案如下:

#include<iostream>
#include<string>
using namespace std;
int main(){
    long long n;
    string s;
    cin>>s;
    n=s.length();
    long long cost=0;
    long long sum=((n+1)*n)/2;
    for(int i=0;i<n;i++){
        int temp=s[i]-'0';
        if((temp!=(i%2==0)?1:0)){
            cost+=(i+1);
        }
    }
    cout<<((cost<=(sum-cost))?cost:(sum-cost))<<endl;
    return 0;
}

好吧,不是dp不行是我不会,我太菜了