数论+dp Codeforces Beta Round #2 B
http://codeforces.com/contest/2/problem/B
题目大意:给你一个n*n的矩形,问从(1,1)出发到(n,n),把图中经过的所有的数字都乘在一起,最后这个数字有多少个0?
思路:经过分析,只有2和5出现的时候才会有0.所以我们预处理把这个数包含的所有的2和5都给拿出来就好了。但是我发现如果每次转移都要统计2和5的个数的话,状态就炸了,所以我只想到了这里TAT。后来看了一下题解以后发现,只需要知道目前到这个位置以后最小的2(或5)的个数就好了。
然后转移我也想了好半天。。。于是还是看了。。。2333(我好菜啊)
转移就是只需要知道最后最小的个数是2还是5,然后再通过该数字去转移就好了
于是早上+中午+下午3个小时就过去了= =
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
const LL inf = 1e17;
LL a[maxn][maxn];
pair<LL, LL> p[maxn][maxn];
LL dp[maxn][maxn][];
int n;
/*
定义dp[i][j]表示到(i,j)所经过的0的最少的个数
0只在2*5的时候出现,所以只需要统计2和5的个数即可
以上思路是行不通的,因为这样子的话dfs或者dp都会有两个变量,所以会超级难写(TAT我写了一个早上)
所以我们要找一下两者当中的共同点。我们只需要找目前状态的2或5的最大值就好了
*/
pair<LL, LL> cal(LL val){
pair<LL, LL> cnt = mk(, );
LL tmp = val;
while (val % == && val) {cnt.fi++; val /= ;}
val = tmp;
while (val % == && val) {cnt.se++; val /= ;}
return cnt;
}
vector<char> v; bool dfs(int x, int y, int k){///0 is first, 1 is second
//printf("x = %d y = %d\n", x, y);
if (x > n || y > n || x < || y < ) return false;
if (x == && y == ) return true;
if (dp[x - ][y][k] < dp[x][y - ][k]){
if (dfs(x - , y, k)) {v.push_back('D'); return true;}
}
else {
if (dfs(x, y - , k)) {v.push_back('R'); return true;}
}
return false;
} int main(){
cin >> n;
memset(p, -, sizeof(p));
bool flag = false;
pair<int, int> zero;
for (int i = ; i <= n; i++){
for (int j = ; j <= n; j++){
scanf("%lld", &a[i][j]);
p[i][j] = cal(a[i][j] == ? : a[i][j]);///当做10,先消去0的影响
if (a[i][j] == ) {flag = true; zero = mk(i, j);}
}
}
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++){
for (int k = ; k < ; k++)
dp[i][j][k] = inf;
if (p[i][j].fi == -) p[i][j] = mk(inf, inf);
}
dp[][][] = p[][].fi, dp[][][] = p[][].se;
for (int i = ; i <= n; i++){
for (int j = ; j <= n; j++){
if (i == && j == ) continue;
dp[i][j][] = min(dp[i - ][j][], dp[i][j - ][]) + p[i][j].fi;
dp[i][j][] = min(dp[i - ][j][], dp[i][j - ][]) + p[i][j].se;
}
}
/*
haha;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
printf("%lld%c", min(dp[i][j][0], dp[i][j][1]), j == n ? '\n' : ' ');
*/
LL ans = min(dp[n][n][], dp[n][n][]);
if (flag && ans >= flag){
ans = 1LL * flag;
printf("%lld\n", ans);
int cnt = ;
for (int i = ; i <= zero.fi; i++) printf("D"), cnt++;
for (int i = ; i < n; i++) printf("R"), cnt++;
for (int i = zero.fi + ; i<= n; i++) printf("D"), cnt++;
cout << endl;
return ;
}
printf("%lld\n", ans);
dfs(n, n, dp[n][n][] > dp[n][n][]);
for (int i = ; i < v.size(); i++)
printf("%c", v[i]);
cout << endl;
return ;
} /*
4
1 10 10 10
1 0 1 10
10 10 2 10
1 10 1 1
*/
数论+dp Codeforces Beta Round #2 B的更多相关文章
- 暴力/DP Codeforces Beta Round #22 (Div. 2 Only) B. Bargaining Table
题目传送门 /* 题意:求最大矩形(全0)的面积 暴力/dp:每对一个0查看它左下的最大矩形面积,更新ans 注意:是字符串,没用空格,好事多磨,WA了多少次才发现:( 详细解释:http://www ...
- 状压dp Codeforces Beta Round #8 C
http://codeforces.com/contest/8/problem/C 题目大意:给你一个坐标系,给你一个人的目前的坐标(该坐标也是垃圾桶的坐标),再给你n个垃圾的坐标,这个人要捡完所有的 ...
- Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)
Codeforces Beta Round #17 题目链接:点击我打开题目链接 大概题意: 给你 \(b\),\(n\),\(c\). 让你求:\((b)^{n-1}*(b-1)\%c\). \(2 ...
- Codeforces Beta Round #16 E. Fish (状压dp)(概率dp)
Codeforces Beta Round #16 (Div. 2 Only) E. Fish 题目链接:## 点击打开链接 题意: 有 \(n\) 条鱼,每两条鱼相遇都会有其中一只吃掉对方,现在给你 ...
- Codeforces Beta Round #13 C. Sequence (DP)
题目大意 给一个数列,长度不超过 5000,每次可以将其中的一个数加 1 或者减 1,问,最少需要多少次操作,才能使得这个数列单调不降 数列中每个数为 -109-109 中的一个数 做法分析 先这样考 ...
- Codeforces Beta Round #62 题解【ABCD】
Codeforces Beta Round #62 A Irrational problem 题意 f(x) = x mod p1 mod p2 mod p3 mod p4 问你[a,b]中有多少个数 ...
- Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】
Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...
- Codeforces Beta Round #77 (Div. 2 Only)
Codeforces Beta Round #77 (Div. 2 Only) http://codeforces.com/contest/96 A #include<bits/stdc++.h ...
- Codeforces Beta Round #67 (Div. 2)
Codeforces Beta Round #67 (Div. 2) http://codeforces.com/contest/75 A #include<bits/stdc++.h> ...
随机推荐
- android 知识点
版本更新 数据库Relam 图片加载库 视频bilibili 幻灯片 网络请求框架 内存检测工具 内存优化总结 压缩包下载并且解压 新闻资讯导航 联系人 滑动退出activity mvp框架 加载进度 ...
- $(#form :input)与$(#form input)的区别
相信大家都很奇怪这两者的区别 我从两个方面简单介绍下 1. $("form :input") 返回form中的所有表单对象,包括textarea.select.button等 ...
- Okhttp设置http缓存,在没有网络的情况下加载http缓存里面的内容
HTTP_CACHE_FILENAME为缓存地址根路径: private final String HTTP_CACHE_FILENAME = "HttpCache"; priva ...
- PHP截取含中文的混合字符串长度的函数
截取含中文的混合字符串长度 /** * 截取中文混合字符串指定长度 * * @param string $string * @param integer $length * @param string ...
- React Redux学习笔记
React Router React Router 使用教程 Redux中间件middleware [译]深入浅出Redux中间件 Redux学习之一:何为middleware? ES6 ES6新特性 ...
- STS中Maven配置
最近接触maven, 配置过程中记录一下. STS是解压版的,启动后,可以看到已经有了Maven插件, , 但是,STS也同时给你了一个Maven,但是通常不建议使用STS自带的maven.使用默认的 ...
- HDU 1335 Basically Speaking(进制转换)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1335 Problem Description The Really Neato Calculator ...
- POJ 1042 Gone Fishing#贪心
(- ̄▽ ̄)-* #include<iostream> #include<cstdio> #include<cstring> using namespace std ...
- hdu_5904_LCIS(DP)
题目链接:hdu_5904_LCIS 题意: 给你两串数,让你找这两串数的最长公共子序列,并且这个最长公共子序列是连续的数值 题解: 我们首先先分别处理出a,b的每个数的最长连续的长度 然后随便找一串 ...
- java.net.NoRouteToHostException: No route to host
报错信息: java.net.NoRouteToHostException: No route to host at java.net.PlainSocketImpl.socketCon ...