题目大意:给你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]);
}