• [TJOI2015]组合数学


    原题

    题目描述

    为了提高智商,ZJY开始学习组合数学。某一天她解决了这样一个问题:给一个网格图,其中某些格子有财宝。每次从左上角出发,只能往右或下走。问至少要走几次才可能把财宝全捡完。

    但是她还不知足,想到了这个问题的一个变形:假设每个格子中有好多块财宝,而每一次经过一个格子至多只能捡走一块财宝,其他条件不变,至少要走几次才可能把财宝全捡完?

    这次她不会做了,你能帮帮她吗?

    输入输出格式

    输入格式:

    第一行为一个正整数t,表示数据组数

    每组数据的第一行是两个正整数n和m,表示这个网格图有n行m列。

    接下来n行,每行m个非负整数,表示这个格子中的财宝数量(0表示没有财宝)。

    输出格式:

    对于每组数据,输出一个整数,表示至少走的次数。

    输入输出样例

    输入样例#1: 
    1
    3 3
    0 1 5
    5 0 0
    1 0 0
    输出样例#1: 
    10

    说明

    数据范围

    对于30%的数据,n≤5.m≤5,每个格子中的财宝数不超过5块。

    对于50%的数据,n≤100,m≤100,每个格子中的财宝数不超过1000块

    对于100%的数据,n≤1000,m≤1000,每个格子中的财宝不超过10^6块

    分析

    当你做这道题的时候你会发现数据大的超乎你想像(DP都超时)!!!

    所以一定会用到数学定理!

    但是是什么数学定理呢?

    就是这个定理(不用知道怎么证明):最长反链长度 = 最小链覆盖数

    最长反链长度 = 最小链覆盖数:

    大前提:在有向无环图中

    链是一个点的集合,这个集合中任意两个元素v、u,要么v能走到u,要么u能走到v。
    反链是一个点的集合,这个集合中任意两点谁也不能走到谁。
     
    最长反链是反链中最长的那个。
     
    那么最长反链怎么求呢?
     
    另一个东西叫:最小链覆盖。就是用最少的链,经过所有的点至少一次(为什么不叫最少链覆盖啊囧……)
    于是Dilwordth定理来了:最长反链长度 = 最小链覆盖数
     
     
     
     
    知道这个定理后再结合DP:f[i][j]=第i行第j列的点的最长反链长度
    由此我们得出了状态转移方程:f[i][j]=max(f[i+1][j],max(f[i][j-1],f[i+1][j-1]+a[i][j]))
     注意:dp的顺序是从下到上、从左到右!!!

    代码

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int t,a[1005][1005],f[1005][1005];
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		int n,m;
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++)
    		    for(int j=1;j<=m;j++)
    		        scanf("%d",&a[i][j]);
    	    for(int i=n;i>=1;i--)
    	        for(int j=1;j<=m;j++)
    	            f[i][j]=max(f[i+1][j],max(f[i][j-1],f[i+1][j-1]+a[i][j]));
    	    printf("%d
    ",f[1][n]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SpringBoot集成Redis
    独享锁 & 共享锁
    公平锁与非公平锁
    如何上传本地代码到码云
    SpringBoot+Mybatis+Pagehelper分页
    SpringBoot集成Mybatis(0配置注解版)
    高并发下接口幂等性解决方案
    SpringBoot全局配置文件
    干货
    Spring读取外部的资源配置文件—@PropertySource和@Value实现资源文件配置
  • 原文地址:https://www.cnblogs.com/chenjiaxuan/p/10700696.html
Copyright © 2020-2023  润新知