POJ_3373_Changing Digits_DP
2015-05-05 23:18
190 查看
好想去游泳。
题意
一个不超过100位的数字n和一个不超10000的数字k,改变其中的一些数字(可以改变0个数字),得到一个新的数字m,满足下列条件:长度和n相同,除0外无前缀0
m可以被k整除
m尽可能改变少的数字
3优先的情况下m尽可能小
IO
InputThere are multiple test cases for the input. Each test case consists of two lines, which contains n(1≤n≤10100) and k(1≤k≤104, k≤n) for each line. Both n and k will not contain leading zeros.
Output
Output one line for each test case containing the desired number m.
分析
做出来以后看了看题解,发现用搜索做的人还用了抽屉原理,然后推出来只需要改变5位就可以搜出来因此只搜最后五位。然而这道题条件的优先级是改变数量少优先于改变后数字小,因此并没有什么卵用。我用的是DP+记录DP路径,这题的DP搜索顺序挺坑爹的。
dp[i][j]定义为到第i位,除k余数为j时需要改变的数量。
dp[i][j]=min(dp[i][j], dp[ii][jj]),遍历当前位的数字l来递推,ii,jj为另一个i, j编号
min操作使得递推肯定抱枕改变的位数最小。
由于需要使数值最小,高位数字需要更大权利,因此从后向前遍历i,每一层i选择当前数字l都从0到9遍历,余数最不重要放在最里层。i从后向前遍历的原因可以从终点那里看出来。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define MXL 110 #define MXK 10010 #define INF 0x3f3f3f3f char a[MXL]; int k; int dp[MXL][MXK]; int pre[MXL][MXK]; int rec[MXL][MXK]; char ans[MXL]; int anscur; int main(){ while(scanf("%s%d",a,&k)!=EOF){ int len=strlen(a); anscur=0; memset(ans,0,sizeof(ans)); memset(dp,0x3f,sizeof(dp)); memset(pre,-1,sizeof(pre)); dp[len][0]=0; int t=1; for(int i=len;i>0;--i){ if(i!=len) t*=10; t%=k; for(int l=0;l<10;++l) for(int j=0;j<k;++j) if(dp[i][j]!=INF){ if(len>1&&i==1&&l==0) continue; int tem=1-(l==a[i-1]-'0'); if(dp[i][j]+tem<dp[i-1][(j+l*t)%k]){ dp[i-1][(j+l*t)%k]=dp[i][j]+tem; pre[i-1][(j+l*t)%k]=j; rec[i-1][(j+l*t)%k]=l; } } } int nowl=0,nowj=0; while(nowl<len){ ans[anscur++]=rec[nowl][nowj]+'0'; nowj=pre[nowl][nowj];++nowl; } printf("%s\n",ans); } return 0; }
相关文章推荐
- POJ 3373 Changing Digits(DP)
- POJ 3373 Changing Digits(记录路径的dp)
- POJ 3373 Changing Digits 好蛋疼的DP
- POJ 3373 Changing Digits 好蛋疼的DP
- POJ 3373 Changing Digits(DP)
- poj 3373 Changing Digits
- POJ-3373 (DP)
- POJ 3373 Changing Digits
- poj 3373 Changing Digits
- poj 3373 数论常识(数位dp)
- poj3373--Changing Digits(DFS+剪枝///记忆化)
- poj 3373 Changing Digits(打表 + dfs + 剪枝 )
- POJ 3373 Changing Digits 记忆化搜索
- poj 3373 Changing Digits(记忆化搜索)
- poj 3373 Changing Digits
- POJ 3373 Changing Digits
- POJ 3373 Changing Digits
- poj3373——Changing Digits
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
- POJ 3373--Changing Digits