Codeforces 2B - The least round way
阿新 • • 發佈:2018-02-05
out syn bool first ons ems 答案 ret tdi
2B - The least round way
思路:
dp。
先算出每個數2因子的個數,和5因子的個數
因為要出現0那麽要1個2乘1個5,那麽最後的答案是min(2的個數,5的個數)
所以我們可以分開考慮,先算出使2最小的方案,再算出使5最小的方案,然後再取最小就可以了。
註意特判一種情況,如果經過一次0,那麽答案只有1個0,再和上面那種情況比較一下,取個最小
mp[i][j][0]表示(i,j)這個位置2因子的個數
mp[i][j][1]表示(i,j)這個位置5因子的個數
狀態:dp[i][j][0]表示到(i,j)這個位置2的最小個數
dp[i][j][1]表示到(i,j)這個位置5的最小個數
初始狀態:dp[1][1][0]=mp[1][1][0]
dp[1][1][1]=mp[1][1][1]
目標狀態:dp[n][n][0],dp[n][n][1]
狀態轉移:dp[i][j][s]=min(dp[i-1][j][s]+mp[i][j][s],dp[i][j-1][s]+mp[i][j][s])
代碼:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mkp make_pair #definepii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e3+5; int dp[N][N][2],mp[N][N][2]; pii pre[N][N][2]; void dfs(int x,int y,int s){ if(x==1&&y==1)return ; dfs(pre[x][y][s].first,pre[x][y][s].second,s); if(pre[x][y][s].first==x-1)cout<<‘D‘; else cout<<‘R‘; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,T,ix,iy; cin>>n; bool f=false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>T; if(T==0){ mp[i][j][0]=mp[i][j][1]=1; ix=i,iy=j; f=true; continue; } int t=0,tt=0; while(T%2==0){ T/=2; t++; } while(T%5==0){ T/=5; tt++; } mp[i][j][0]=t; mp[i][j][1]=tt; } } mem(dp,0x3f); for(int i=0;i<2;i++){ dp[1][1][i]=mp[1][1][i]; for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ if(j==1&&k==1)continue; if(dp[j-1][k][i]+mp[j][k][i]<dp[j][k][i]){ dp[j][k][i]=dp[j-1][k][i]+mp[j][k][i]; pre[j][k][i]=mkp(j-1,k); } if(dp[j][k-1][i]+mp[j][k][i]<dp[j][k][i]){ dp[j][k][i]=dp[j][k-1][i]+mp[j][k][i]; pre[j][k][i]=mkp(j,k-1); } } } } //cout<<dp[n][n][0]<<‘ ‘<<dp[n][n][1]<<endl; int s,ans; if(dp[n][n][0]<dp[n][n][1])ans=dp[n][n][0],s=0; else ans=dp[n][n][1],s=1; if(f){ if(ans>1){ cout<<1<<endl; for(int i=0;i<ix-1;i++)cout<<‘D‘; for(int i=0;i<n-1;i++)cout<<‘R‘; for(int i=ix-1;i<n-1;i++)cout<<‘D‘; } else{ cout<<ans<<endl; dfs(n,n,s); } } else{ cout<<ans<<endl; dfs(n,n,s); } return 0; }
Codeforces 2B - The least round way