快速排序 - dp - 四边形不等式

题目大意:给你n个b位二进制数,你可以将某个数字的某一位修改,问最少多少次修改使得答案不降。n<=1000,b<=50
题解:显然有一个O(n^3b)的dp,然后观察到其有决策单调性,直接类似四边形不等式优化即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
const int N=1003,B=52;int v[N][B];
int dp[2][N][N],fr[N][N],zc[B][N],oc[B][N];
int main()
{
    int n,b;scanf("%d%d",&n,&b);
    rep(i,1,n) rep(j,1,b) scanf("%1d",&v[i][j]);
    rep(i,1,b) rep(j,1,n) zc[i][j]=zc[i][j-1]+(v[j][i]==0),oc[i][j]=oc[i][j-1]+v[j][i];
    for(int i=b-1;i>=0;i--)
    {
        int (*now)[N]=dp[i&1],(*nxt)[N]=dp[(i+1)&1];
        rep(j,1,n) now[j][j]=0,fr[j][j]=(v[j][i+1]==0?j:j-1);
        rep(len,2,n) rep(j,1,n-len+1)
        {
            int k=j+len-1;now[j][k]=INT_MAX;
            rep(t,fr[j][k-1],fr[j+1][k])
            {
                int res=nxt[j][t]+nxt[t+1][k]+oc[i+1][t]-oc[i+1][j-1]+zc[i+1][k]-zc[i+1][t];
                if(res<now[j][k]) now[j][k]=res,fr[j][k]=t;
            }
        }
    }
    return !printf("%d\n",dp[0][1][n]);
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/88534426