题解链接:http://pan.baidu.com/s/1dFHAlIL 密码:ug38
#include<bits/stdc++.h>
#define cp(a,x) memcpy(a,x,sizeof a)
using namespace std;
const int N=20002,inf=(1ll<<31)-1;
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
return x*f;
}
int n,m,q,a[N],p0[52];
char s[52][N];
int f[N],t[N],g[N];
struct Q{
int q[N],l,r,d;
void pre(){l=1,r=0;}
void add(int x){
if(f[x]==inf)return;
int u=f[x]-a[x]*d;
while(l<=r){
int y=q[r];
if(f[y]-a[y]*d>=u)--r; else break;
}
q[++r]=x;
}
void del(int x){
if(l<=r && q[l]==x)++l;
}
int get(int w){
if(l>r)return inf;
int x=q[l];
return f[x]+(a[w]-a[x])*d;
}
}qs[52];
int main(){
n=read(),m=read(),q=read();
for(int i=1;i<=m;++i) a[i]=read()+a[i-1];
for(int i=1;i<=n;++i){
scanf("%s",s[i]+1); qs[i].d=i;
for(int j=1;j<=m && s[i][j]=='1';++j) f[j]+=a[j];
}
printf("%d\n",f[m]);
for(int i=2;i<=q;++i){
for(int j=0;j<=n;++j) p0[j]=0,qs[j].pre();
f[0]=inf;
for(int j=1;j<=m;++j){
qs[t[j]=n].add(j-1);
for(int k=1;k<=n;++k) if(s[k][j]=='0'){
for(int z=p0[k]+1;z<=j;++z){
qs[t[z]].del(z-1);
qs[--t[z]].add(z-1);
}
p0[k]=j;
}
g[j]=inf;
for(int k=0;k<=n;++k) g[j]=min(g[j],qs[k].get(j));
}
cp(f,g);
printf("%d\n",f[m]);
}
return 0;
}