http://codeforces.com/gym/101257/problem/C

询问从左上角走到右下角,每次只能向右或者向左,捡起三种物品算作一个logo,求最多能得到多少个logo。

设dp[i][j][k][h]表示走到(i, j)这个格子,然后得到的第一种物品是k,第二种物品是h的时候,能得到的第三个物品的最大值是多少。

-inf表示不存在这个状态,其实第三种物品可以算出来,因为一共的步数就是i + j - 1,所以捡起的物品数量是固定的。

所以直接这样dp下去即可,是一个背包问题。

然后会MLE,所以我把第一维滚动了。(不会把第二维也滚动,一直出不了样例)

有一个小bug就是,每种物品最多都是可以捡200个,n + m - 1个,一定要都枚举是否成立。

一开始我只枚举到67个,因为67 * 3 = 201,logo数目其实最多就是66

但是会wa。还想不到数据

可能dp应该是要遍历所有可能的结果,只不过是选最优,有一些部分被抛弃了而已。

所以枚举到200吧,毕竟它最多能捡起200个。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e2 + ;
char str[maxn][maxn];
int n, m;
int dp[][maxn][ + ][ + ];
int pre(int id) {
if (id == ) return ;
else return id - ;
}
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
scanf("%s", str[i] + );
}
memset(dp, -0x3f, sizeof dp);
dp[][][][] = ;
dp[][][][] = ;
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
int en = i + j - ;
for (int k = en; k >= ; --k) {
for (int h = en; h >= ; --h) {
dp[i % ][j][k][h] = -inf;
if (str[i][j] == '>') {
if (k < ) {
dp[i % ][j][k][h] = -inf;
continue;
}
dp[i % ][j][k][h] = dp[pre(i % )][j][k - ][h];
dp[i % ][j][k][h] = max(dp[i % ][j][k][h], dp[i % ][j - ][k - ][h]);
} else if (str[i][j] == '|') {
if (h < ) {
dp[i % ][j][k][h] = -inf;
continue;
}
dp[i % ][j][k][h] = dp[pre(i % )][j][k][h - ];
dp[i % ][j][k][h] = max(dp[i % ][j][k][h], dp[i % ][j - ][k][h - ]);
} else {
dp[i % ][j][k][h] = dp[pre(i % )][j][k][h] + ;
dp[i % ][j][k][h] = max(dp[i % ][j][k][h], dp[i % ][j - ][k][h] + );
}
}
}
}
}
int ans = ;
for (int i = ; i <= ; ++i) {
for (int j = ; j <= ; ++j) {
ans = max(ans, min(i, min(j, dp[n % ][m][i][j])));
// if (dp[n % 3][m][i][j] >= 0) {
// cout << i << " " << j << " " << dp[n % 3][m][i][j] << endl;
// }
}
}
cout << ans << endl; } int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

最新文章

  1. DB2常用sql命令
  2. 转 异常处理汇总 ~ 修正果带着你的Net飞奔吧!
  3. 图片流量节省大杀器:基于CDN的sharpP自适应图片技术实践
  4. KETTLE、spoon使用
  5. 中小企业 IT 运维福利:快速构建 on-call 机制
  6. 【noip2007】树网的核
  7. 【转】Spring 注解学习手札(超好的springmvc注解教程)
  8. ASP.Net【如何合并DataTable,并且去重复方法】
  9. js--局部变量
  10. [iOS Animation]-CALayer 图层性能
  11. 流API--缩减操作
  12. QT之setstylesheet防止子窗体继承父窗体样式
  13. [Swift]LeetCode677. 键值映射 | Map Sum Pairs
  14. Python中的__new__()方法与实例化
  15. oracle-gi安装
  16. 2018.10.20 loj#2593. 「NOIP2010」乌龟棋(多维dp)
  17. NDK编程jni学习入门,声明native方法,使其作为java与c的交互接口
  18. 部署Jar包到远程Maven仓库
  19. PreparedStatementSQLException
  20. MAC 通过brew安装软件

热门文章

  1. Eclipse设置java环境
  2. spring boot 打印sql
  3. Spring Boot2.0之 整合Redis集群
  4. easyUI-右键菜单,关闭选项卡
  5. 小米2在Eclipse 调试,要注意下列步骤。(转)
  6. mysql 5.5升级到5.7版本操作流程
  7. hdu-2066 一个人的旅行(最短路spfa)
  8. linux学习二(小随笔)
  9. 【AMPPZ 2014】 The Captain
  10. 在Ubuntu下获取Android4.0源代码并编译(一)