zoukankan      html  css  js  c++  java
  • 【题解】CF2B The least round way

    The least round way

    ( ext{Solution:})

    第一种想法:设 (dp[i][j][k]) 表示格子 ((i,j)) 尾数是 (k) 的最少零的个数,转移需要枚举尾数。

    由于要输出路径,空间开不下而 GG .

    第二种:考虑为什么会出现 (0:) 十进制下只有 (2,5) 相乘才可以。所以一个位置上最少的零的个数应该是 (minleft{Num_2,Num_5 ight})

    于是考虑对这两个东西进行 dp 。设 (f[i][j]) 是到达格子 ((i,j)) 的最少 (2) 的个数, (g[i][j]) 对应 (5) 的个数。

    那么对这两个东西进行转移即可。同时记录一下路径。

    如果格子中有 (0) 的话,则答案必然不高于 (1) 特判一下即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int dyx=(1<<30);
    int n,a[1001][1001];
    int f[1001][1001],g[1001][1001];
    int numt[1001][1001],numf[1001][1001];
    int FG,F[1001][1001];
    pair<int,int> pret[1001][1001],pref[1001][1001];
    pair<int,int> pos0;
    inline int Min(int x,int y) {
    	return x<y?x:y;
    }
    void print(pair<int,int> path,int t){
    	int fir=path.first;
    	int sec=path.second;
    //	printf("(%d %d)
    ",fir,sec);
    	if(fir==1&&sec==1)return;
    	if(t==1)print(pret[fir][sec],t);
    	else print(pref[fir][sec],t);
    	if(t==1){
    		if(pret[fir][sec].first<fir)printf("D");
    		else printf("R");
    	}
    	else{
    		if(pref[fir][sec].first<fir)printf("D");
    		else printf("R");
    	}
    }
    int main() {
    	freopen("CF2B.txt","r",stdin);
    	//f[i][j] g[i][j]
    	scanf("%d",&n);
    	for(int i=1; i<=n; ++i)
    		for(int j=1; j<=n; ++j) {
    			f[i][j]=g[i][j]=dyx;
    			scanf("%d",&a[i][j]);
    			if(a[i][j]==0)FG=1,pos0=make_pair(i,j),F[i][j]=1;
    			int cnt=0;
    			int x=a[i][j];
    			while(x%2==0&&x)cnt++,x/=2;
    			numt[i][j]=cnt;cnt=0;
    			while(x%5==0&&x)cnt++,x/=5;
    			numf[i][j]=cnt;cnt=0;
    		}
    //	for(int i=1;i<=n;++i)
    //		for(int j=1;j<=n;++j)
    //			printf("(%d %d)%c",numt[i][j],numf[i][j],j==n?'
    ':' ');
    	for(int i=0;i<=n;++i)
    		for(int j=0;j<=n;++j)
    			f[i][j]=g[i][j]=dyx;
    	f[1][1]=numt[1][1];
    	g[1][1]=numf[1][1];
    	for(int i=1; i<=n; ++i) {
    		for(int j=1; j<=n; ++j) {
    			if(i==1&&j==1)continue;
    			if(F[i][j])continue;
    			if(f[i-1][j]<f[i][j-1])pret[i][j]=make_pair(i-1,j);
    			else pret[i][j]=make_pair(i,j-1);
    			f[i][j]=Min(f[i-1][j],f[i][j-1])+numt[i][j];
    			if(g[i-1][j]<g[i][j-1])pref[i][j]=make_pair(i-1,j);
    			else pref[i][j]=make_pair(i,j-1);
    			g[i][j]=Min(g[i-1][j],g[i][j-1])+numf[i][j];
    		}
    	}
    //	for(int i=1;i<=n;++i)
    //		for(int j=1;j<=n;++j)
    //			printf("(%d %d)%c",f[i][j],g[i][j],j==n?'
    ':' ');
    //	puts("PathF:");
    	int ans=dyx;
    //	for(int i=1;i<=n;++i){
    //		for(int j=1;j<=n;++j){
    //			printf("(%d %d) ",pret[i][j].first,pret[i][j].second);
    //		}
    //		puts("");
    //	}
    //	puts("PathG:");
    //	for(int i=1;i<=n;++i){
    //		for(int j=1;j<=n;++j){
    //			printf("(%d %d) ",pref[i][j].first,pref[i][j].second);
    //		}
    //		puts("");
    //	}
    	ans=Min(ans,Min(f[n][n],g[n][n]));
    	if(!FG||(FG&&ans<=1)){
    		printf("%d
    ",ans);
    		if(f[n][n]<g[n][n]){
    //			if(pret[n][n].first<n)printf("R");
    //			else printf("D");
    			print(make_pair(n,n),1);
    		}
    		else {
    //			if(pref[n][n].first<n)printf("R");
    //			else printf("D");
    			print(make_pair(n,n),0);
    		}
    		puts("");
    	}
    	else {
    		puts("1");
    		for(int i=1;i<pos0.first;++i)printf("D");
    		for(int i=1;i<pos0.second;++i)printf("R");
    		for(int i=1;i<=n-pos0.first;++i)printf("D");
    		for(int i=1;i<=n-pos0.second;++i)printf("R");
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    欢迎使用CSDN-markdown编辑器
    欢迎使用CSDN-markdown编辑器
    Math类简介
    Math类简介
    http_server
    tcp服务器
    swoole安装
    laravel源码解析
    VMware的Unity模式
    string.format() %d越界的问题
  • 原文地址:https://www.cnblogs.com/h-lka/p/14981460.html
Copyright © 2011-2022 走看看