poj3373--Changing Digits(DFS+剪枝///记忆化)
2017-09-20 17:54
375 查看
题目链接:点击打开链接
题目大意:给出一个n和一个k 求m
要求1、m要和n相同的位数
要求2、m要整除k
要求3、如果1和2满足,那么m要和n有尽量少的不同位
要求4、如果1、2、3满足,要使m尽量的小
简单的一个深搜,但是直接被要求吓蒙,,,,,
要求1和2直接可以在搜索时判断,要求3可以在深搜时给出可以改变的位数(有0到len(n)),而要求4需要控制在搜索是要从小的开始搜,即从100000到999999,因为在深搜之前就控制了可以改变的次数,所以在搜索时不用担心要求3,只要使要求1要求2满足就可以,那么搜到的第一个就是最小的。
注意剪枝:
1、在每一次变化后都要直接计算出余数,当余数为0时,返回1,而不是一定要搜到最后一位。
mod[i][j] = (j*10^i)%k
2、flag[i][j]当搜到第i位余数为j时,没有找到结果的(修改位数),当以后遇到修改位数<=flag[i][j]时直接返回0。
代码快来拿
题目大意:给出一个n和一个k 求m
要求1、m要和n相同的位数
要求2、m要整除k
要求3、如果1和2满足,那么m要和n有尽量少的不同位
要求4、如果1、2、3满足,要使m尽量的小
简单的一个深搜,但是直接被要求吓蒙,,,,,
要求1和2直接可以在搜索时判断,要求3可以在深搜时给出可以改变的位数(有0到len(n)),而要求4需要控制在搜索是要从小的开始搜,即从100000到999999,因为在深搜之前就控制了可以改变的次数,所以在搜索时不用担心要求3,只要使要求1要求2满足就可以,那么搜到的第一个就是最小的。
注意剪枝:
1、在每一次变化后都要直接计算出余数,当余数为0时,返回1,而不是一定要搜到最后一位。
mod[i][j] = (j*10^i)%k
2、flag[i][j]当搜到第i位余数为j时,没有找到结果的(修改位数),当以后遇到修改位数<=flag[i][j]时直接返回0。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char str[110]; int k,len,a[110]; int mod[110][10]; int flag[110][11000]; void init(){ for(int j=0;j<10;j++) mod[0][j]=j%k; for(int i=1;i<110;i++) for(int j=0;j<10;j++) mod[i][j]=mod[i-1][j]*10%k; } int dfs(int num,int pos,int s){ if(s == 0) return 1; if(num == 0 || pos == -1) return 0; if(num <= flag[pos][s]) return 0; int temp ; for(int i=0;i<=9;i++){ if(pos == len-1 && i == 0 ) continue; if(i<a[pos]){ temp=a[pos]-i; a[pos]=i; if(dfs(num-1,pos-1,(s-mod[pos][temp]+k)%k)) return 1; a[pos]+=temp; } else if(i == a[pos]){ if(dfs(num,pos-1,s)) return 1; } else{ temp=i-a[pos]; a[pos]=i; if(dfs(num-1,pos-1,(s+mod[pos][temp])%k)) return 1; a[pos]-=temp; } } flag[pos][s]=max(flag[pos][s],num); return 0; } int main(){ int i,j,s,temp; while(scanf("%s %d",str,&k)!=EOF){ memset(flag,-1,sizeof(flag)); len=strlen(str); for(i=len-1;i>=0;i--){ a[len-1-i]=str[i]-'0' ; } init(); for(i=s=temp=0;i<len;i++){ s=(mod[i][a[i]]+temp)%k ; temp=s; } for(i=0;i<=len;i++){ if(dfs(i,len-1,s)) break; } for(i=len-1;i>=0;i--) printf("%d",a[i]); printf("\n"); } return 0; } /* 535064 9084 535956 19169 15724 15724 3902 153 3978 */
代码快来拿
相关文章推荐
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
- poj3373——Changing Digits
- POJ 3373 Changing Digits
- poj 3373 Changing Digits
- poj 3373 Changing Digits
- poj 3373 Changing Digits
- POJ 3373--Changing Digits
- POJ 3373 Changing Digits 好蛋疼的DP
- poj 3373 Changing Digits(记忆化搜索)
- POJ 3373 Changing Digits 好蛋疼的DP
- poj 3373 Changing Digits
- POJ-3373-Changing Digits
- poj3373--Changing Digits(DFS+剪枝///记忆化)
- POJ 3373 Changing Digits
- POJ 3373 Changing Digits(记录路径的dp)
- POJ 3373 Changing Digits(DP)
- POJ 3373 Changing Digits
- POJ 3373 Changing Digits
- POJ_3373_Changing Digits_DP
- POJ 3373 Changing Digits