zoukankan      html  css  js  c++  java
  • bzoj 3997 [TJOI2015]组合数学(DP)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=3997

    【题意】

        给定一个nm的长方形,每次只能使经过格子权值减1,每次只能向右向下,问最少需要走多少次才能使所有格子权值为0.

    【思路】

       

        因为每次只能向右或向下走,所以对于(i,j)和(i’,j’)当且仅当两点任一个不在另一个的左下方时两点才不在同一条路径上。

        将长方形反转左右。

        设f[i][j]为使以ij右下角的长方形权值为0的走的最少次数,则有转移式:

            f[i][j]=max{ max{ f[i-1][j],f[i][j-1] },f[i-1][j-1]+a[i][j] }

        含义为选一个点集和最大的点集,使得点集中的任意两个节点满足不在同一条路径上,最大点集和即为答案。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int N = 1e3+10;
     8 
     9 int n,m;
    10 int f[N][N],mp[N][N];
    11 
    12 ll read() {
    13     char c=getchar(); ll f=1,x=0;
    14     while(!isdigit(c)) {
    15         if(c=='-') f=-1; c=getchar();
    16     }
    17     while(isdigit(c))
    18         x=x*10+c-'0',
    19         c=getchar();
    20     return x*f;
    21 }
    22 
    23 int main()
    24 {
    25     int T;
    26     T=read();
    27     while(T--) {
    28         memset(f,0,sizeof(f));
    29         n=read(),m=read();
    30         for(int i=1;i<=n;i++) {
    31             for(int j=m;j;j--) mp[i][j]=read();
    32         }
    33         for(int i=1;i<=n;i++)
    34             for(int j=1;j<=m;j++)
    35                 f[i][j]=max(max(f[i-1][j],f[i][j-1]),f[i-1][j-1]+mp[i][j]);
    36         printf("%d
    ",f[n][m]);
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    聊一聊HTML <pre>标签
    [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法
    数据库的权限管理
    完整性约束
    MYSQL
    Python并发编程之协程
    python并发编程之多线程
    python并发编程之多进程
    进程
    网络编程之socket的运用
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5298963.html
Copyright © 2011-2022 走看看