codeforces 230C Shifts DP

来源:互联网 发布:lol西门淘宝代练室 编辑:程序博客网 时间:2024/05/18 01:10

题意:一个01矩阵,每一行上的数字都可以向左向右移动(具体看题目描述),求最小的操作数,是矩阵某一列都是1.

做法:一开始,没看清题意,没有把从一侧推到另一侧的情况考虑进去...

#include <iostream>#include <algorithm>#include <cstdio>#define eps 1e8using namespace std;int dp[102][10004],work[102][10004];int main(){    int n,m,pre,now,ans,first;    char x;    scanf("%d%d",&n,&m);    getchar();    for(int i=0;i<=n;i++)    {        fill(work[i],work[i]+m,eps);        fill(dp[i],dp[i]+m,eps);    }    for(int i=0;i<n;i++)    {        first=now=pre=-1;      for(int j=0;j<m;j++)      {         x=getchar();         x-='0';          if(x)          {              pre=now;              now=j;              if(first==-1)first=j;              work[i][j]=0;              for(int t=pre+1;t<now;t++)              {                  if(pre!=-1)work[i][t]=t-pre;                  work[i][t]=min(now-t,work[i][t]);              }          }      }      getchar();        if(now!=-1)         {            pre=now;            for(int t=pre+1;t<m;t++)            work[i][t]=t-pre;         }        if(first!=-1)        {           for(int t=pre+1;t<m;t++)             work[i][t]=min(work[i][t],first+m-t);           for(int t=0;t<first;t++)           work[i][t]=min(work[i][t],m-pre+t);        }    }    for(int i=0;i<n;i++)      for(int j=0;j<m;j++)          if(!i)dp[i][j]=work[i][j];          else if(dp[i-1][j]!=eps&&work[i][j]!=eps)dp[i][j]=dp[i-1][j]+work[i][j];          ans=eps;          for(int j=0;j<m;j++)ans=min(ans,dp[n-1][j]);          if(ans>=eps)printf("-1\n");          else printf("%d\n",ans);    return 0;}


原创粉丝点击