• HDU 4939 Stupid Tower Defense 简单DP


    题意:

      地图为长为n个单位长度的直线,每通过一个单位长度需要t秒。

      有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后格子造成y点伤害,蓝塔可以使通过单位长度的时间增加z秒。

      让你安排塔的排列是造成的伤害最大。

    思路:

      最开始想到dp,状态dp[i][r][g][b]表示:假设前i格放了r个红塔、g个绿塔和b个蓝塔,枚举第i+1格放什么。

      因为长度最大为1500,所以如果这样开状态的话,需要1500^4的空间,这显然是开不下的。

      后来想到,一种塔的数量可以表示成总数减去另外两种塔的数量,这样的话,就可以减掉一维,变成dp[i][g][b],还是会超空间。

      然后想到,红塔只在当前格子有效,所以不用记录有多少红塔,只需要知道有多少绿塔和蓝塔就好了,也不用记录当前是第几格。所以状态变成了dp[g][b]。

      但是,这样子时间复杂度仍然是n^3的,会超时。

      可以证明,如果存在红塔,放在后面一定比放在前面更优。所以,只需要dp前面有g个绿塔和b个蓝塔时候造成的最大伤害,然后在求解的时候计算出后面全是红塔。 所以,时间复杂度也变成了n^2。这样子就可以解了。

    代码:

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <queue>
     9 #include <stack>
    10 #include <vector>
    11 #include <map>
    12 #include <set>
    13 #include <functional>
    14 #include <time.h>
    15 
    16 using namespace std;
    17 
    18 typedef __int64 ll;
    19 
    20 const int INF = 1<<30;
    21 const int MAXN = 1555;
    22 
    23 ll dp[MAXN][MAXN]; //dp[i][j]: 前面i+j个塔中,有i个green,j个blue
    24 ll n, x, y, z, t;
    25 
    26 void solve() {
    27     scanf("%I64d%I64d%I64d%I64d%I64d", &n, &x, &y, &z, &t);
    28 
    29     memset(dp, 0, sizeof(dp));
    30     for (int i = 0; i < n; i++)
    31         for (int j = 0; j+i < n; j++) {
    32             dp[i+1][j] = max(dp[i+1][j], dp[i][j]+(i*y)*(t+j*z));
    33             dp[i][j+1] = max(dp[i][j+1], dp[i][j]+(i*y)*(t+j*z));
    34         }
    35 
    36     ll ans = 0;
    37     for (int i = 0; i <= n; i++)
    38         for (int j = 0; i+j <= n; j++)
    39             ans = max(ans, dp[i][j]+((n-i-j)*(x+i*y))*(t+z*j));
    40 
    41     printf("%I64d
    ", ans);
    42 }
    43 
    44 int main() {
    45     #ifdef Phantom01
    46         freopen("HDU4939.txt", "r", stdin);
    47     #endif //Phantom01
    48 
    49     int T;
    50     scanf("%d", &T);
    51     for (int i = 1; i <= T; i++) {
    52         printf("Case #%d: ", i);
    53         solve();
    54     }
    55 
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    一、Redis源码结构
    StringUtils工具类用法
    什么是多态
    Spring事务配置的五种方式
    不错的spring学习博客
    hibernate.current_session_context_class 比较权威的解释
    搞搞hibernate.current_session_context_class
    Spring MVC @Transactional注解方式事务失效的解决办法
    spring 中 hibernate 的 2种 配置方式(新旧 2种方式)
    Spring+Hibernate整合配置 --- 比较完整的spring、hibernate 配置
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3909427.html
Copyright © 2020-2023  润新知