zoukankan      html  css  js  c++  java
  • AtCoder

    题意:

    给你一个n行m列由'#'和'.'构成的矩阵,你需要从(1,1)点走到(n,m)点,你每次只能向右或者向下走,且只能走'.'的位置。

    你可以执行操作改变矩阵:

    你可以选取两个点,r0,c0;r1,c1。以(r0,c0)为小矩阵左上角坐标,以(r1,c1)为小矩阵右下角坐标。你要把这个小矩阵中的所有字符反转(也就是原来是'#'的,要变成'.',原来是'.'的,要变成'#')

    题解:

    对于样例

    3 3
    .##
    .#.
    ##.

    我们可以看成反转之后的矩阵最终从(1,1)走到(n,m)的只有一条路径,不管其他点(如下,*号就是我们最终选择的路径)

    3 3
    .*#
    .*.
    #*.

    那么我们就可以反转(1,1)和(2,3)这个小矩阵,或者(2,1),(2,3)这个小矩阵。(1,1)和(2,3)这个小矩阵反转的时候虽然涉及到了一些其他点(第一列所有点),但是我们最终要走的路径没有用到它,所以不用管它。

    代码:

    #include <bits/stdc++.h>
    typedef long long ll;
    const int maxn = 1e2 + 10;
    const int INF = 0x3f3f3f3f;
    char s[maxn][maxn];
    int dp[maxn][maxn];
    int min(int a, int b)
    {
        if (a < b)
            return a;
        else
            return b;
    }
    int max(int a, int b)
    {
        if (a > b)
            return a;
        else
            return b;
    }
    int main()
    {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; ++i)
        {
            scanf("%s", s[i] + 1);
        }
        dp[1][1] = (s[1][1] == '#');
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 1; j <= m; ++j)
            {
                if (i == 1 && j == 1)
                    continue;
                char ch = s[i][j];
                dp[i][j] = INF;
                if (i > 1)
                {
                    if (s[i - 1][j] == ch)
                        dp[i][j] = min(dp[i][j], dp[i - 1][j]);
                    else
                        dp[i][j] = min(dp[i][j], dp[i - 1][j] + (ch == '#'));
                }
                if (j > 1)
                {
                    if (s[i][j - 1] == ch)
                        dp[i][j] = min(dp[i][j], dp[i][j - 1]);
                    else
                        dp[i][j] = min(dp[i][j], dp[i][j - 1] + (ch == '#'));
                }
            }
        }
        printf("%d
    ", dp[n][m]);
        return 0;
    }

     

    POJ - 2336 题意:

    现在有m辆车在左岸,你需要用一艘船把所有车运送到右岸,每次船只能运送n辆车。船过河的时间为t(也就是一来一回所需时间2*t)。

    问你把所有车运送到右岸最少是什么时候,在这个基础上给出最少运送次数(运送次数不算船从右岸返回到左岸)

    题目给你m辆车到达左岸的时间点vi。

    题解:

    暴力转移dp,dp[i]表示把前i辆车运送到右岸之后船又回到左岸的最小时间点

    dp[i]=max(dp[j],v[i]); (1<=j<=i<=n)
    dp[i]+=2*t;
    cnt[i]=cnt[j]+1;

    代码:

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn = 2e3 + 10;
    const int INF=0x3f3f3f3f;
    int max(int a,int b)
    {
        if(a>b) return a;
        else return b;
    }
    int v[maxn],cnt[maxn],dp[maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,t,m;
            scanf("%d%d%d",&n,&t,&m);
            for(int i=1;i<=m;++i)
            {
                scanf("%d",&v[i]);
            }
            for(int i=1;i<=m;++i)
            {
                dp[i]=INF;
                for(int j=i-n;j<i;++j)
                {
                    if(dp[i]>max(dp[j],v[i]))
                    {
                        dp[i]=max(dp[j],v[i]);
                        cnt[i]=cnt[j]+1;
                    }
                }
                dp[i]+=2*t;
            }
            printf("%d %d
    ",dp[m]-t,cnt[m]);
        }
        return 0;
    }
  • 相关阅读:
    ado.net
    sql基础
    css样式
    HTML基础加强
    socket网络编程
    网络聊天室
    多线程
    WinForm基础
    使用Maven插件(plugin)MyBatis Generator逆向工程
    SpringBoot使用thymeleaf时候遇到无法渲染问题(404/500)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/14101237.html
Copyright © 2011-2022 走看看