【问题描述】
小空正在玩一个叫做捡金币的游戏。游戏在一个被划分成 n行 n列的网格状场地中进行。
每一个格子中都放着若干金币,并且金币的数量会随着时间而不断变化。 小空的任务就是在
网格中移动,拾取尽量多的金币。 并且,小空还有一个特殊技能“闪现”, 能帮助她在网格间
快速移动。
捡金币游戏的具体规则如下:在每一秒开始时,每个网格内都会出现一定数量的金币,
而之前在这格没有被拾取的金币就消失了。在游戏开始时,也就是第 1 秒的开始,小空可以
选择任意一个网格作为起点开始本次游戏,并拾取起点内的金币。之后,在下一秒到来前,
小空可以选择走路移动到与她所在的格子上、下、左、右相邻的一个格子中,或者呆在原地
不动,并在下一秒开始时拾取到她所在的格子中的金币。或者,小空可以选择使用闪现技能,
使用一次闪现时,她先选择上、下、左、右一个方向,之后向该方向移动两格。小空可以在
一秒内使用多次闪现,但不能超过 C 次。在一秒内使用的多次闪现必须向同一个方向移动,
若使用 x 次闪现,便可以向一个方向移动正好 2x 格,并且她也只能在下一秒开始时收集到
连续闪现结束后所在的那一格中的金币。如果在某一秒钟小空使用了闪现,那么她就不能选
择通过走路移动了,反过来也是如此。无论走路或者使用闪现,小空都不能移动到整个场地
之外。整个游戏共进行 T 秒,在第 T 秒开始时,小空将会拾取她所在的格子中的金币,并结
束游戏。 小空在整局游戏内一共只能使用最多 W 次闪现。

现在,给出游戏场地的大小 n,每秒钟开始时各个位置会出现的金币数,小空一秒内最
多使用闪现的次数 C, 小空在整局游戏中使用闪现的最多次数 W,整局游戏的总时间 T,请
你告诉小空她最多可以获得多少枚金币。

【输入】

输入的第 1 行包含 4 个整数 n, C, W, T,意义如问题描述中所述。
接下来包含 n 个 n*n 的矩阵,第 k 个矩阵的第 i 行第 j 列表示第 i 行第 j 列的格子在第 k
秒开始时出现的金币数( 记作si,j,k)。 相邻两个矩阵间用一个空行隔开。
【 输出】
输出包含一个整数,表示游戏结束时小空最多可以获得的金币数量。
【输入输出样例 1】

coin.in coin.out
3 1 1 3
1 3 4
3 2 1
1 3 2
2 3 1
1 3 2
2 1 4
3 3 1
3 2 1
2 3 1
11

见选手目录下的 coin / coin1.in 与 coin / coin1.out
【输入输出样例 1 说明】
选择在第 1 行第 3 列开始游戏, 获得 4 枚金币;在第 2 秒开始时向下闪现到第 3 行第 3
列, 获得 4 枚金币;在第 3 秒开始时向左走到第 3 行第 2 列,获得 3 枚金币, 游戏结束。一
共获得 11 枚金币。
【输入输出样例 2】
见选手目录下的 coin / coin2.in 与 coin / coin2.out
【数据规模与约定】

测试点编号 n C W T si,j,k
1 ≤5 ≤2 ≤4 ≤5 ≤1,000
2
3
4 ≤21 ≤10 ≤80 ≤80
5
6
7 ≤25 =100 ≤150 ≤100
8
9 ≤12
10

对 100%的数据, n≥1, C≥0, W≥0, T≥1, si,j,k≥0

/*
方程并不难,主要通过这个题学一下单调队列
*/
#include <cstdio>
#define inf 1000000007
int a[202][33][33],f[2][33][33][202],q[33],qc[33],v[33][202],cnt,n,C,W,T,i,j,k,t,ii,jj,kk,tt,l,r,ans,ch,tag;void read(int &x)
{for (ch=getchar(); ch<=32; ch=getchar());for (x=0; ch>32; ch=getchar()) x = x*10+ch-48;
}void update(int &x, int y)
{if (y > x) x = y;
}void clear()
{l=1; r=0;q[0] = inf;q[1] = -inf;cnt = 0;
}void push(int x)
{q[++r] = x;qc[r] = 1;q[r+1] = -inf;while (q[r] >= q[r-1]){qc[r-1] += qc[r];q[r-1] = q[r];q[r--] = -inf;}if (++cnt > C) if (--qc[l] == 0) q[l++] = inf;
}int main()
{freopen("coin.in", "r", stdin);freopen("coin.out", "w", stdout);scanf("%d%d%d%d", &n, &C, &W, &T);for (t=1; t<=T; ++t)for (i=1; i<=n; ++i)for (j=1; j<=n; ++j) read(a[t][i][j]);for (i=1; i<=n; ++i)for (j=1; j<=n; ++j) f[0][i][j][0] = a[1][i][j];t = 0;for (tt=2; tt<=T; ++tt){t ^= 1;for (i=1; i<=n; ++i)for (j=1; j<=n; ++j)for (k=0; k<=W; ++k) f[t][i][j][k] = -inf;for (i=1; i<=n; ++i){++tag;for (jj=1; jj<=n; ++jj)for (kk=0; kk<=W; ++kk)if (v[jj][kk] != tag){clear();j = jj;k = kk;while (j<=n && k<=W){v[j][k] = tag;update(f[t][i][j][k], q[l]);push(f[t^1][i][j][k]);j += 2;k++;}}++tag;for (jj=n; jj>=1; --jj)for (kk=0; kk<=W; ++kk)if (v[jj][kk] != tag){clear();j = jj;k = kk;while (j>=1 && k<=W){v[j][k] = tag;update(f[t][i][j][k], q[l]);push(f[t^1][i][j][k]);j -= 2;k++;}}}for (j=1; j<=n; ++j){++tag;for (ii=1; ii<=n; ++ii)for (kk=0; kk<=W; ++kk)if (v[ii][kk] != tag){clear();i = ii;k = kk;while (i<=n && k<=W){v[i][k] = tag;update(f[t][i][j][k], q[l]);push(f[t^1][i][j][k]);i += 2;k++;}}++tag;for (ii=n; ii>=1; --ii)for (kk=0; kk<=W; ++kk)if (v[ii][kk] != tag){clear();i = ii;k = kk;while (i>=1 && k<=W){v[i][k] = tag;update(f[t][i][j][k], q[l]);push(f[t^1][i][j][k]);i -= 2;k++;}}}for (i=1; i<=n; ++i)for (j=1; j<=n; ++j)for (k=0; k<=W; ++k){update(f[t][i][j][k], f[t^1][i-1][j][k]);update(f[t][i][j][k], f[t^1][i+1][j][k]);update(f[t][i][j][k], f[t^1][i][j-1][k]);update(f[t][i][j][k], f[t^1][i][j+1][k]);update(f[t][i][j][k], f[t^1][i][j][k]);f[t][i][j][k] += a[tt][i][j];}}for (i=1; i<=n; ++i)for (j=1; j<=n; ++j)for (k=0; k<=W; ++k) update(ans, f[t][i][j][k]);printf("%d\n", ans);return 0;
}

转载于:https://www.cnblogs.com/hyfer/p/5965147.html

清北学堂模拟day4 捡金币相关推荐

  1. 清北学堂模拟赛d5t4 套路

    分析:题目非常短,看起来非常难,其实把图一画就明白了.有向图,每个点的出度都是1,那么整个图肯定是环上套链,链上的边无论怎样反向都不会形成环,环上的边也可以随便反向,但是最终不能反为同向的,总方案数减 ...

  2. 清北学堂模拟赛d3t2 b

    分析:一道比较让人头疼的数学题. 先考虑怎么让分出来的三角形相似,先不考虑每个三角形的具体边长,设每个三角形的周长为li,则可知必然有一个数g = gcd{li},每一个三角形的周长都是g的倍数,这样 ...

  3. 清北学堂模拟赛d6t3 反击数

    分析:显然是一道数位dp题,不过需要一些奇怪的姿势.常规的数位dp能统计出一个区间内满足条件的数的个数,可是我们要求第k个,怎么办呢?转化为经典的二分问题,我们二分当前数的大小,看它是第几大的,就可以 ...

  4. 清北学堂模拟赛d2t4 最大值(max)

    题目描述 LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目: 这里有一个长度为n的正整数数列ai(下标为1~n).并且有一个参数k. 你需要找两个正整数x,y,使得x+k< ...

  5. 清北学堂模拟赛d1t1 位运算1(bit)

    题目描述 LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值. 假设数字N的价值是K,LYK想找到 ...

  6. 清北学堂模拟赛day7 错排问题

    /* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...

  7. 清北学堂模拟赛d6t4 数组异或

    分析:直接O(n^3)做是只有50分的,可以加一点小小的优化,就是c[k]可以从c[k-1]得到,但是还是只有60分,从宏观意义上是不能继续优化了.对于这类涉及到位运算的性质的题目,将每个数转化成二进 ...

  8. 清北学堂模拟赛d6t2 刀塔

    分析:看到最小值最大就很显然是二分了吧,二分一下最小值,把小于它的数给删掉,然后看每个数向左边能延伸多长,往右边能延伸多长,最后统计一下有没有可行答案就可以了. #include <cstdio ...

  9. 清北学堂模拟赛d3t6 c

    分析:比较神奇的一道题.要把树变成环肯定要先变成链,然后把链给拼接成环.接下来考虑一个脑洞大开的树形dp:设f[i][0]表示i不与父节点相连的链数,f[i][1]表示i与父节点相连的链数,先考虑怎么 ...

  10. 8月清北学堂培训 Day4

    今天上午是赵和旭老师的讲授~ 概率与期望 dp 概率 某个事件 A 发生的可能性的大小,称之为事件 A 的概率,记作 P ( A ) . 假设某事的所有可能结果有 n 种,每种结果都是等概率,事件 A ...

最新文章

  1. 结对编程-马尔科夫链作业成绩
  2. 30天敏捷生活(5):形成个人价值观
  3. 云计算应用还有不少的障碍尚需解决
  4. LINUX修改文件权限 学习
  5. 这群程序员疯了!他们想成为IT界最会带货的男人
  6. 2019 ACM/ICPC 全国邀请赛(西安)J And And And (树DP+贡献计算)
  7. 线程与进程,你真的清楚吗?
  8. linux php添加扩展zip libzip ZipArchive功能
  9. Slider控件的使用方法
  10. c# 委托和委托事件
  11. 开学蓝牙耳机选哪个?音质好的蓝牙耳机排行
  12. 电子签章安全用印方案:系统“三员分立”+印章“三权分立”
  13. java编程比赛_[阶段一]java基础编程比赛
  14. vmware虚拟机WinXp sp3的系统cpu占用100%的解决方案
  15. HTML5移动端手机网站开发流程
  16. 日文图片翻译器扫描_微信如何巧变中英文翻译器?三招教你解决翻译难题
  17. matlab图上输入希腊字母,Matlab中给图形添加【希腊字母】
  18. (Fabric学习坑)com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;
  19. 汇编指令学习(CMP,TEST)
  20. 参考文献的类型--参考文献里的J、M等字母都代表什么

热门文章

  1. Orchard核心机制
  2. 163网站顶部展出的大幅广告
  3. (转载)找工作那年,我真的哭了
  4. 数据结构之链表(Linked list)
  5. java 图形化界面 布局管理器
  6. Unity3D播放背景音乐
  7. WinForm中ComBoBox绑定显示值和实际值
  8. iOS应用的真机调试
  9. HHF_MySQL数据类型_简述
  10. linux块设备缓存bcache