zoukankan      html  css  js  c++  java
  • [NOIP2008]传纸条

    嘟嘟嘟

    一道人人皆知的dp基础题。我听人讲了无数遍,就是没写。

    问题可以转化为找到两条从(1, 1)到(n, m)不相交的路径,使路径上的好感度之和最大。

    这道题的关键在于dp的顺序,观察会发现,只要保持这两条路径枚举到同一条对角线上,顺序就对了。于是令dp[k][i][j]表示到第k条对角线,靠右的点的纵坐标为 i ,靠左点的纵坐标为 j 时的答案。每一个点有两种转移方式,所以一共有四种转移方式。枚举即可。

    最后的状态应该是dp[n + m - 1][n - 1][n],而不是dp[n + m][n][n],因为要保证两条路径不相交,那么dp[n + m][n][n]显然是一个不合法状态,所以答案是这个状态的上一个状态。

    另外可以倒着枚举优化掉第一维,但对于这一题来说没有必要。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 55;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) last = ch, ch = getchar();
    26   while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m, a[maxn][maxn];
    38 ll dp[maxn << 1][maxn][maxn];
    39 
    40 int main()
    41 {
    42   n = read(); m = read();
    43   for(int i = 1; i <= n; ++i)
    44     for(int j = 1; j <= m; ++j) a[i][j] = read();
    45   for(int k = 3; k < n + m; ++k)
    46     for(int i = 1; i < k - 1; ++i)
    47       for(int j = i + 1; j < k; ++j)
    48     {
    49       ll tp = 0;
    50       tp = max(tp, dp[k - 1][i][j]);
    51       tp = max(tp, dp[k - 1][i - 1][j]);
    52       if(j - 1 != i) tp = max(tp, dp[k - 1][i][j - 1]);
    53       tp = max(tp, dp[k - 1][i - 1][j - 1]);
    54       dp[k][i][j] = tp + a[i][k - i] + a[j][k - j];
    55     }
    56   write(dp[n + m - 1][n - 1][n]), enter;
    57   return 0;
    58 }
    View Code
  • 相关阅读:
    c#自动更新+安装程序的制作
    VS2013项目受源代码管理向源代码管理注册此项目时出错
    WinDbg配置和使用基础
    InstallShield Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
    PowerDesigner 如何生成数据库更新脚本
    用户故事(User Story)
    Troubleshooting Record and Playback issues in Coded UI Test
    Coded UI
    compare two oracle database schemas
    How to: Use Schema Compare to Compare Different Database Definitions
  • 原文地址:https://www.cnblogs.com/mrclr/p/9881173.html
Copyright © 2011-2022 走看看