zoukankan      html  css  js  c++  java
  • Codeforces 225C Barcode(矩阵上DP)

    题目链接:http://codeforces.com/contest/225/problem/C

    题目大意:

    给出一个矩阵,只有两种字符'.'和'#',问最少修改多少个点才能让每一列的字符一致,且字符一致的连续的列的宽度在x和y之间。

    解题思路:

    先求出每列‘.’和'#'的前缀和,sum[i][0]表示前i列'#' 的前缀和,sum[i][1]表示前i列'.' 的前缀和 ,因为修改要求每列都保持一直,其实我们可以将每列都当成一个点来看,那样我们就相当于是在一维序列上操作了。

     dp[i][0]表示最后一列为'.'的最优解,dp[i][1]表示最后一列为'#'的最优解 。

    那么我们可以得到状态转移方程:

    dp[i+j][0]=min(dp[i+j][0],dp[i][1]+sum[i+j][0]-sum[i][0]),x=<j<=y,0<=i<=m
    dp[i+j][1]=min(dp[i+j][1],dp[i][0]+sum[i+j][1]-sum[i][1]),x=<j<=y,0<=i<=m

    其实很好理解,dp[i+j][0]表示第i+j列为'.',那么可以由相差为j的第i列为'#'的状态推导过来,同时要将i+1~j的'#'都变为'.'

    dp[i+j][1]同理。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<string>
     6 #include<string.h>
     7 #include<cctype>
     8 #include<math.h>
     9 #include<stdlib.h>
    10 #include<stack>
    11 #include<queue>
    12 #include<set>
    13 #include<map>
    14 #define lc(a) (a<<1)
    15 #define rc(a) (a<<1|1)
    16 #define MID(a,b) ((a+b)>>1)
    17 #define fin(name)  freopen(name,"r",stdin)
    18 #define fout(name) freopen(name,"w",stdout)
    19 #define clr(arr,val) memset(arr,val,sizeof(arr))
    20 #define _for(i,start,end) for(int i=start;i<=end;i++)  
    21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    22 using namespace std;
    23 typedef long long LL;
    24 const int N=3e3+5;
    25 const LL INF64=1e18;
    26 const int INF=0x3f3f3f3f;
    27 const double eps=1e-10;
    28 
    29 int dp[N][2];  //dp[i][0]表示最后一列为'.'的最优解,dp[i][1]表示最后一列为'#'的最优解 
    30 int sum[N][2]; //sum[i][0]表示前i列'#' 的前缀和,sum[i][1]表示前i列'.' 的前缀和 
    31 
    32 int main(){
    33     memset(dp,0x3f,sizeof(dp));
    34     FAST_IO;
    35     int n,m,x,y;
    36     cin>>n>>m>>x>>y;
    37     for(int i=1;i<=n;i++){
    38         for(int j=1;j<=m;j++){
    39             char x;
    40             cin>>x;
    41             if(x=='#')
    42                 sum[j][0]++;
    43             else
    44                 sum[j][1]++;
    45         }
    46     }    
    47     for(int i=1;i<=m;i++){
    48         sum[i][0]+=sum[i-1][0];
    49         sum[i][1]+=sum[i-1][1];
    50     }
    51 
    52     dp[0][0]=dp[0][1]=0;
    53     for(int i=0;i<=m;i++){
    54         for(int j=x;j<=y;j++){
    55             dp[i+j][0]=min(dp[i+j][0],dp[i][1]+sum[i+j][0]-sum[i][0]);
    56             dp[i+j][1]=min(dp[i+j][1],dp[i][0]+sum[i+j][1]-sum[i][1]);
    57         }
    58     }
    59     cout<<min(dp[m][0],dp[m][1])<<endl;
    60     return 0;
    61 }
  • 相关阅读:
    iphone 自学常用网址
    @ApiParam @RequestParam @PathVariable 用法
    @RestController 与 @Controller 注解区别
    Java:post请求
    Java:清空文件内容
    Java:追加文件内容
    Java:获取文件内容
    Java:Md5加密
    Java:获取IP地址
    docker:安装tomcat
  • 原文地址:https://www.cnblogs.com/fu3638/p/9131467.html
Copyright © 2011-2022 走看看