zoukankan      html  css  js  c++  java
  • 【XDOJ】小W的塔防

    原题:

    小W在成功拿到iPhone后,下载了一个塔防游戏。游戏的目标是阻止僵尸穿过地图。

    地图可以看作一条长度为n的线段,这条线段被划分为n条单位长度的小线段。僵尸需要花费t秒才能通过一条小线段。在每条小线段中,小W可以放置1个塔。塔有3种:

    红色塔,每秒对正在通过塔的敌人造成x点伤害。

    绿色塔,每秒对已经通过塔的敌人造成y点伤害。

    蓝色塔,使已经通过塔的敌人减速,需要多花费z秒才能通过1单位长度。

    “正在通过”定义为僵尸处于塔所在的单位长度小线段,“已经通过”定义为僵尸已经离开了这条小线段。

    绿色塔、蓝色塔的效果可以叠加。换句话说,如果一个僵尸已经通过了a个绿色塔,b个蓝色塔,它将每秒受到来自绿色塔的ay点伤害,并且花费t+bz秒才能通过1单位长度。

    小W希望知道,他至多可以给僵尸造成多少伤害。

    1<=n<=100,0<=x,y,z<=60000,1<=t<=3

    n很小,冰塔和毒塔的数量又不可能超过n

    所以一眼f[i][j][k] n^3 DP,表示僵尸走到第i个线段,踩了j个毒塔,k个冰塔能吃掉的最大伤害

    但是我没有1A,问题在哪里呢

    一开始我是这样写的

    1 for(int i=1;i<=n;++i)
    2     for(int j=0;j<=i;++j)
    3         for(int k=0;j+k<=i;++k){
    4             f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+(x+j*y)*(t+k*z));
    5             if(j)  f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]+(j-1)*y*(t+k*z));
    6             if(k)  f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j*y*(t+(k-1)*z));
    7         }

    然后f初值是0

    结果样例没过,因为这样子有可能从f[0][1][0]转移到f[1][1][0]

    然后我草率地把j<=i和j+k<=i改成j<i和j+k<i

    显然这样是不对滴,注意j和k表示的是走过第i个线段时,踩了j个毒塔k个冰塔,之前的表述是不清楚的

    喜闻乐见地WA了

    正确改法应该是f初值全设-INF,f[0][0][0]设成0

    突然想起来这个做法还是挺常见的,用来防止非法状态乱入

    可能是退坑一年忘了吧哈哈

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 long long n,x,y,z,t;
     8 long long f[110][110][110];
     9 void rvs(){
    10     for(int i=0;i<=n;++i)
    11         for(int j=0;j<=n;++j)
    12             for(int k=0;k<=n;++k)
    13                 f[i][j][k]=-9999999999999999LL;
    14     f[0][0][0]=0;
    15     return ;
    16 }
    17 int main(){
    18     //freopen("ddd.in","r",stdin);
    19     while(scanf("%lld%lld%lld%lld%lld",&n,&x,&y,&z,&t)!=EOF){
    20         rvs();
    21         for(int i=1;i<=n;++i)
    22             for(int j=0;j<=i;++j)
    23                 for(int k=0;j+k<=i;++k){
    24                     f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+(x+j*y)*(t+k*z));
    25                     if(j)  f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]+(j-1)*y*(t+k*z));
    26                     if(k)  f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j*y*(t+(k-1)*z));
    27                 }
    28         long long ans=0;
    29         for(int i=0;i<=n;++i)
    30             for(int j=0;j<=n;++j)
    31                 ans=max(ans,f[n][i][j]);
    32         printf("%lld
    ",ans);
    33     }
    34     return 0;
    35 }
    View Code
  • 相关阅读:
    结队-贪吃蛇游戏-项目进度
    团队-象棋游戏-开发环境搭建过程
    团队-中国象棋游戏-设计文档
    结对-贪吃蛇游戏-开发环境搭建过程
    结对-结对编项目贪吃蛇-设计文档
    课后作业-阅读任务-阅读提问-1
    《20170911-构建之法:现代软件工程-阅读笔记》
    团队-中国象棋-成员简介及分工
    团队-团队编程项目中国象棋-需求分析
    结队-结队编程项目贪吃蛇--需求分析
  • 原文地址:https://www.cnblogs.com/cdcq/p/11334991.html
Copyright © 2011-2022 走看看