数论+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> ...
随机推荐
- 表单与JQuery
表单: Html标签注意: 1.提交action 2.提交按钮:类型一定为type="submit" ,不然无反应 3. Jquery: 个人认为属于JS 1.一般不用表单提交 2 ...
- win10下安装Django
Django的核心(1.4+)可以运行在从2.5到2.7之间的任何Python版本. 我的电脑是操作系统是window10 ,内存是4G. 1.下载django 官网地址:https://www.dj ...
- oracle 写入txt
分几个步骤 1,创建输出路径,比如你要在/orcl/dir目录下输出,你就先要建立好这个路径,并在root用户下 chmod 777 /orcl/dir 2,sqlplus下以sysdba登录,执行以 ...
- 关于cocos2dx的C++调用创建项目
我使用的是cocos2dx-2.1.4版本+cygwin,其实主要是为了配合公司项目,所以用了低版本的cocos2dx 假设已经配置环境成功: 按照对应的要求输入包名,项目名,以及TargetId,就 ...
- JVM 几个重要的参数
<本文提供的设置仅仅是在高压力, 多CPU, 高内存环境下设置> 最近对JVM的参数重新看了下, 把应用的JVM参数调整了下. 几个重要的参数 -server -Xmx3g -Xms3 ...
- java对数计算
Java对数函数的计算方法非常有问题,然而在API中却有惊人的误差.但是假如运用了以下的方法,用Java处理数字所碰到的小麻烦就可以轻而易举的解决了. Sun的J2SE提供了一个单一的Java对数方法 ...
- 有关下行HARQ的一切
1. 对于下行HARQ,有几种类型的下行传输需要UE反馈ACK/NACK 动态调度的下行传输:UE收到一个使用C-RNTI或TC-RNTI(对应随机接入过程中的Msg4)加扰的PDCCH和PDSCH, ...
- Office Web Apps安装部署(一)
来源于:http://www.cnblogs.com/poissonnotes/p/3238238.html 系统要求为Windows Server 2012, 注意:安装Office Web App ...
- Linux下gcc编译生成动态链接库*.so文件并调用它【转载】
动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...
- MySQL DATE_FORMAT
MySQL DATE_FORMAT(date,format) 根据format字符串格式化date值 (在format字符串中可用标志符: %M 月名字(January……December) %W ...