• 【SCOI2009】粉刷匠


    题目

    DP

    为在第 i 行 j 列 粉刷 k 次 粉刷蓝色(1)/红色(0)

    那很容易想出方程转移式

     

    f[i][j][k][1]=max(f[i][j-1][k][1],f[i][j-1][k-1][0])+(a[i][j]==1);f[i][j][k][0]=max(f[i][j-1][k-1][1],f[i][j-1][k][0])+(a[i][j]==0);

    但是我们会发现Bug


    如果 j=1时,本应从上一行最后一个转移过来,但现在我们会从0转移过来

    所以要特判一下

    如果 j=1 时方程转移式为

     

    f[i][j][k][1]=max(f[i-1][m][k-1][1],f[i-1][m][k-1][0])+(a[i][j]==1);

    f[i][j][k][0]=max(f[i-1][m][k-1][1],f[i-1][m][k-1][0])+(a[i][j]==0);

     

    最后ans为f[n][m][1~t][0/1]中最大的

    上代码

     

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int f[55][55][2505][2],n,m,t,a[55][55];
    int main()
    {
        scanf("%d%d%d",&n,&m,&t);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                scanf("%1d",&a[i][j]);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                for (int k=1;k<=t;k++)
                {
                    if (j==1)
                    {
                        f[i][j][k][1]=max(f[i-1][m][k-1][1],f[i-1][m][k-1][0])+(a[i][j]==1);
                        f[i][j][k][0]=max(f[i-1][m][k-1][1],f[i-1][m][k-1][0])+(a[i][j]==0);
                    }
                    else
                    {
                        f[i][j][k][1]=max(f[i][j-1][k][1],f[i][j-1][k-1][0])+(a[i][j]==1);
                        f[i][j][k][0]=max(f[i][j-1][k-1][1],f[i][j-1][k][0])+(a[i][j]==0);
                    }
                }
        int ans=0;
        for (int i=1;i<=t;i++) 
            ans=max(ans,max(f[n][m][i][1],f[n][m][i][0]));
        printf("%d
    ",ans);
    }

     

  • 相关阅读:
    微信开发 缓存处理
    ASP.NET MVC 开发日常笔记
    微信开发笔记
    Kindeditor 编辑代码过滤
    PS 使用技巧
    Javascript 日常开发用到的小知识点
    C# 下载文件
    Javascript 笔记一
    C# 知识巩固三
    文献笔记(五)
  • 原文地址:https://www.cnblogs.com/nibabadeboke/p/11327801.html
Copyright © 2020-2023  润新知