LA 3720 highway(利用动态规划思想,将复杂度急降,9ms)

原创 2013年12月01日 21:17:19

题目链接

此题的解决方法可参考:http://blog.csdn.net/incredible_bly/article/details/11821403

这种可以接受,但是还可以更快吗?

计算过程有个 tmp = (m-x+1)*(n-y+1) 这个咋看只能适用于n*m的情况无法扩展,

将其展开: tmp = N*M - N*x - M *y + x*y   [N = n+1 , M = m+1]

此公式非常关键,N和M是变量,计算时只需记录系数即可 , 很容易将其扩展到(n+1)*m 或 n*(m+1) , 转移需要的复杂度是O(min{n,m}), 然后时间从500ms 到 10 ms 的转变。。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 310;
int gcd(int a,int b){
    int r;
    while(b) r=a%b , a=b ,b=r;
    return a;
}
int vis[maxn][maxn] , cnt[maxn][maxn] , X[maxn][maxn] ,Y[maxn][maxn] ,dcnt[maxn][maxn];
int g[maxn][maxn];

void DP(int n,int m){
    if(vis[n][m]) return;
    int &c1=cnt[n][m] , &x1=X[n][m] , &y1 = Y[n][m] ,&d1 = dcnt[n][m];
    if(n==0 || m==0){
        c1 = d1 = x1 = y1 =0;
        vis[n][m] = 1;
        return;
    }
    if(n<m){
        DP(n,m-1);
        c1 = cnt[n][m-1] ,d1=dcnt[n][m-1] , x1=X[n][m-1] , y1=Y[n][m-1];
        for(int y=1;y<=n;y++){
            if(g[m][y]==1){
                c1++,d1+=m*y,x1+=m,y1+=y;
            }
            else if(g[m][y]==2){
                c1--,d1-=m*y,x1-=m,y1-=y;
            }
        }
    }
    else{
        DP(n-1,m);
        c1 = cnt[n-1][m] ,d1=dcnt[n-1][m] , x1=X[n-1][m] , y1=Y[n-1][m];
        for(int x=1;x<=m;x++){
            if(g[x][n]==1){
                c1++,d1+=x*n,x1+=x,y1+=n;
            }
            else if(g[x][n]==2){
                c1--,d1-=x*n,x1-=x,y1-=n;
            }
        }
    }
    vis[n][m] = 1;
    return ;
}
int main()
{
    for(int i=0;i<=300;i++) for(int j=0;j<=300;j++) g[i][j] = gcd(i,j);
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF && n+m){
        n-- , m--;
        if(n>m) swap(n,m);
        DP(n,m);
        int ans = cnt[n][m]*(n+1)*(m+1) - (n+1)*X[n][m] - (m+1)*Y[n][m] + dcnt[n][m];
        ans*=2;
        printf("%d\n",ans);
    }
    return 0;
}


菜鸟学算法——动态规划(二)

概述 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法,它是应用数学中用于解决某类最优化问题的重要工具。20世纪...
  • klqulei123
  • klqulei123
  • 2016年10月10日 20:53
  • 2003

常用算法整理:动态规划上

什么是动态规划动态规划是应该不能叫 一种算法,而应该叫 一类算法 或者 说是 一种思想。它和 二分查找 这种算法是不同的,二分查找我们可以用代码表示出来,并且解决所有问题的思路几乎都是一样的。而动态规...
  • lihongxun945
  • lihongxun945
  • 2016年04月17日 17:47
  • 4756

算法分析与设计实验 动态规划法 求最长公共子序列

实验目的   加深对动态规划法的算法原理及实现过程的理解,学习用动态规划法解决实际应用中的 最长公共子序列问题。 实验内容   内容: 用动态规划法实现求两序列的最长公共子序列,其比较结果可用于基因比...
  • wyh7280
  • wyh7280
  • 2015年05月07日 18:18
  • 1445

一种利用重链剖分优化一类树形动态规划空间复杂度的方法

Origin在某一场GDOI模拟赛上,一道好好的点分治题目,本蒟蒻强行大力优化暴力碾了过去。这题中我算法的瓶颈不在时间复杂度,而在于空间复杂度。为了解决这个问题,我想到了一种使用重链剖分来优化空间复杂...
  • a_crazy_czy
  • a_crazy_czy
  • 2017年04月12日 22:08
  • 307

动态规划求解矩阵连乘的最优时间复杂度

本文介绍如何使用动态规划的思想,寻找矩阵序列连乘的最优时间复杂度。
  • bendanban
  • bendanban
  • 2017年06月30日 21:27
  • 1043

算法导论-第15章-动态规划:最长公共子序列(空间复杂度改进版)C++实现

#include #include #include using namespace std; int LCS(char* A, char* B, int* C, int m, int n) ...
  • DevilDatin
  • DevilDatin
  • 2014年11月27日 16:47
  • 378

Maximum Subsequence Sum[PAT1007][PTA01-复杂度2]——动态规划

Maximum Subsequence Sum 思路 实现Maximum Subsequence Sum思路数据结构视频里面简单的讲了一下动态规划的方法,但这个题还需要输出开始最后的序列数,测试点中包...
  • u013563008
  • u013563008
  • 2016年04月24日 00:35
  • 511

最长回文子串—动态规划和Manacher算法(0(n)时间复杂度

#include #include #include using namespace std; /** * Manacher O(n) * @param string str */ int...
  • zhidao_wenge
  • zhidao_wenge
  • 2017年03月04日 18:33
  • 619

0/1背包问题动态规划 空间复杂度是o(C)

有num个物品,总背包容量为Capacity, 求不超过背包总容量的前提下使得背包里的物品的价值达到最大的物品是哪些物品。 对于每个物品,只有两种选择,要么装要么不装进背包。 那么在考虑前 i 个...
  • u014311181
  • u014311181
  • 2015年11月11日 14:32
  • 332

动态规划算法(微软一面笔试题:股票交易,O(N)时间复杂度O(1)空间复杂度)

自从暑假面试被鄙视之后,回来就经常想这个问题,到今天应该快两个月了。在这个下午,我又拿出草稿纸,总算找到了思路,把它给搞定了。就像一个心愿一样,完结了。问题是这样的,如同题目:原题就不赘述了,化简之后...
  • ClamReason
  • ClamReason
  • 2012年08月24日 15:18
  • 6658
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LA 3720 highway(利用动态规划思想,将复杂度急降,9ms)
举报原因:
原因补充:

(最多只允许输入30个字)