zoukankan      html  css  js  c++  java
  • 洛谷P1174 打砖块

    题目描述

    小红很喜欢玩一个叫打砖块的游戏,这个游戏的规则如下:

    在刚开始的时候,有n行*m列的砖块,小红有k发子弹。小红每次可以用一发子弹,打碎某一列当前处于这一列最下面的那块砖,并且得到相应的得分。(如图所示)

    某些砖块在打碎以后,还可能将得到一发子弹的奖励。最后当所有的砖块都打碎了,或者小红没有子弹了,游戏结束。

    小红在游戏开始之前,就已经知道每一块砖在打碎以后的得分,并且知道能不能得到一发奖励的子弹。小红想知道在这次游戏中她可能的最大得分,可是这个问题对于她来说太难了,你能帮帮她吗?

    输入输出格式

    输入格式:

    第一行有3个正整数,n,m,k。表示开始的时候,有n行*m列的砖块,小红有k发子弹。

    接下来有n行,每行的格式如下:

    f1 c1 f2 c2 f3 c3 …… fm cm

    其中fi为正整数,表示这一行的第i列的砖,在打碎以后的得分。ci为一个字符,只有两种可能,Y或者N。Y表示有一发奖励的子弹,N表示没有。

    所有的数与字符之间用一个空格隔开,行末没有多余的空格。

    输出格式:

    仅一个正整数,表示最大的得分。

    输入输出样例

    输入样例#1:
    3 4 2
    9 N 5 N 1 N 8 N
    5 N 5 Y 5 N 5 N
    6 N 2 N 4 N 3 N
    输出样例#1:
    13

    说明

    对于20%的数据,满足1<=n,m<=5,1<=k<=10,所有的字符c都为N

    对于50%的数据,满足1<=n,m<=200,1<=k<=200,所有的字符c都为N

    对于100%的数据,满足1<=n,m<=200,1<=k<=200,字符c可能为Y

    对于100%的数据,所有的f值满足1<=f<=10000

    如果没有奖励子弹的话,相当于一个分组背包,决策每一列打几个就可以了。

    ↑50分解法

    有奖励子弹的话,就有了特殊情况:例如某一列最下面有x个普通方块,其上面有一串奖励方块,要想拿到奖励方块,必须得预留x+1颗子弹,这多出来的1颗子弹可以在以后用来打之前某列的砖块。

    所以需要多一维状态,处理留一发子弹/不留的情况。

    状态多了有些迷茫,半抄着题解写完……我已经是条咸鱼了。

    f1是留一发子弹的状态,f2是都打完的状态。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=220;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int f1[mxn][mxn],f2[mxn][mxn];//[列][使用子弹数]=最优解 
    17 int n,m,k;
    18 int mp[mxn][mxn];
    19 bool re[mxn][mxn];
    20 int w1[mxn][mxn],w2[mxn][mxn];
    21 void init(){
    22     for(int j=1;j<=m;j++){
    23         int cnt=n;
    24         while(cnt && re[cnt][j]){
    25             w1[j][0]+=mp[cnt][j];
    26             cnt--;
    27         }
    28         for(int i=1;i<=n && cnt ;i++){//打了i发子弹 
    29             w2[j][i]=w1[j][i-1]+mp[cnt][j];
    30             w1[j][i]=w2[j][i];
    31             cnt--;
    32             while(cnt && re[cnt][j]){
    33                 w1[j][i]+=mp[cnt][j];
    34                 cnt--;
    35             }
    36         }
    37     }
    38     return;
    39 }
    40 int main(){
    41     n=read();m=read();k=read();
    42     int i,j;
    43     for(i=1;i<=n;i++)
    44      for(j=1;j<=m;j++){
    45          mp[i][j]=read();
    46          char ch=getchar();
    47          if(ch=='N')re[i][j]=0;
    48          else re[i][j]=1;
    49      }
    50     init();
    51     /*
    52     for(i=1;i<=n;i++){
    53      for(j=1;j<=m;j++){
    54          printf("%5d %5d ",mp[i][j],num[i][j]);
    55      }
    56      printf("
    ");
    57     }*/
    58     for(i=1;i<=m;i++){//
    59         for(j=0;j<=k;j++){//子弹 
    60             for(int l=0;l<=j;l++){//之前已用子弹 
    61                 f1[i][j]=max(f1[i][j],f1[i-1][j-l]+w1[i][l]);
    62                 if(l<j){
    63                     f2[i][j]=max(f2[i][j],f2[i-1][j-l]+w1[i][l]);
    64                 }
    65                 if(l){
    66                     f2[i][j]=max(f2[i][j],f1[i-1][j-l]+w2[i][l]);
    67                 }
    68             }
    69         }
    70     }
    71     printf("%d
    ",f2[m][k]);
    72     return 0;
    73 }
  • 相关阅读:
    Daily Scrumming* 2015.12.19(Day 11)
    Daily Scrumming* 2015.12.18(Day 10)
    软件工程 个人作业1
    网络1711-12&信管1711-12 图 作业评分
    网络1711-12 数据结构第一次作业评分
    Java课程设计
    网络1711-1712班 c 语言评分总表一览
    网络1711班 C语言第八次作业批改总结
    201621123050 《Java程序设计》第14周学习总结
    201621123050 《Java程序设计》第13周学习总结
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6045101.html
Copyright © 2011-2022 走看看