[数位dp] 乘法

虽然听了正解,但是我们还是要好好考虑一下这道题。

我们从高到低的考虑每一位,我们考虑前面还差多少,其实前面一位只会有 \(0\)\(-1\)。因为 \(1\) 我们是无法通过后面的二进制位弥补上的。

我们定义 \(f_i\) 表示还剩 \(i,i=-1\or 0\) 的代价。

我们考虑之前的 \(g_{-1}\) 能够怎么转移。

一种情况是我这一位也需要一个 \(1\),那么我们这一位就是要一个 \(1\) 了,所以 \(\begin{cases}f_0=g_{-1}+1\\ f_{-1}=g_{-1}\end{cases}\)

一种情况是这一位是 \(0\),如果我们之前是一个 \(-1\)\(f_{-1}=g_{-1}+1\)

之前的 \(g_0\) 怎么转移呢?

如果这位是 \(1\)\(f_0=g_{0}+1\)

如果这一位是 \(0\)\(\begin{cases}f_{-1}=g_{0}+1\\f_0=g_0\end{cases}\)

试试吧。

#include <bits/stdc++.h>
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N=1e6+10, inf=0x3f3f3f3f;

string st;
int cnt,f[50],g[50];

void solve(){
    f[0]=0; f[1]=inf;
    st='0'+st;
    for(int i=0;i<st.size();++i){
        g[0]=f[0];g[1]=f[1];
        if(st[i]=='1'){
            f[0]=min(g[1]+1,f[0]+1);
            f[1]=g[1];
        }else{
            f[1]=min(g[1]+1,g[0]+1);
            f[0]=g[0];
        }
    }
    cout<<f[0]*2-1<<endl;
}

int main(){
    cin>>st;
    solve();
    return 0;
}
/*
是谁挥霍的时光啊,是谁苦苦的奢望啊

这不是一个问题,也不需要你的回答

No answer. 
*/
posted @ 2022-09-02 14:32  Mercury_City  阅读(24)  评论(0编辑  收藏  举报