您的位置:首页 > 其它

POJ 3373 Changing Digits(记录路径的dp)

2014-05-29 20:01 423 查看
很长时间之前看的一道题目,一直以为是搜索。结果发现是dp,输出路径即可。

题目大意:给你一个n,k。找一个m使得m的长度与n一样,而且m要尽量多的元素保持和n一样。一样的条件下要选择一个最小的输出。(从小到大枚举就可以满足找到的最小)

dp[i][j] 表示i位置是的余数为j此时有多少位数字是不同的。

pre[i][j][k]k = 1表示第i位余数为j时取得数字是多少,k = 0 表示第i位余数为j时的前一个状态的余数是多少。(记录前驱)。

注意预处理出来大数的余数,这很重要。

Changing Digits

Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 2910 Accepted: 933
Description

Given two positive integers n and k, you are asked to generate a new integer, say m, by changing some (maybe none) digits of n, such that the following properties holds:

m contains no leading zeros and has the same length as n (We consider zero itself a one-digit integer without leading zeros.)
m is divisible by k
among all numbers satisfying properties 1 and 2, m would be the one with least number of digits different from n
among all numbers satisfying properties 1, 2 and 3, m would be the smallest one

Input

There 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.

Sample Input
2
2
619103
3219

Sample Output
2
119103

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 1000100
///#define LL __int64
#define LL long long
#define INF 0x3fffffff
#define PI 3.1415926535898

using namespace std;

const int maxn = 110;

int dp[maxn][maxn*maxn];
int pre[maxn][maxn*maxn][2];
int mod[maxn][10];
char str[maxn];
int k;
int len;

void dfs(int x, int y)
{
if(x > len)
return;
cout<<pre[x][y][1];
dfs(x+1, pre[x][y][0]);
}
int main()
{
while(cin >>(str+1)>>k)
{
len = strlen(str+1);
for(int i = 0; i <= 9; i++)
mod[len][i] = i%k;
for(int i = len-1; i >= 1; i--)
for(int j = 0; j <= 9; j++)
mod[i][j] = (mod[i+1][j]*10)%k;
memset(dp, -1, sizeof(dp));
dp[len+1][0] = 0;
for(int i = len; i >= 1; i--)
{
int p = 0;
if(i == 1)
p = 1;
for(; p <= 9; p++)
{
for(int j = 0; j < k; j++)
{
if(dp[i+1][j] != -1)
{

int ff = 1;
if((str[i]-'0') == p)
ff = 0;
int kk = (mod[i][p]+j)%k;
if(dp[i][kk] == -1 || (dp[i+1][j]+ff < dp[i][kk]))
{
dp[i][kk] = dp[i+1][j]+ff;
pre[i][kk][1] = p;
pre[i][kk][0] = j;
}
}
}
}
}
dfs(1, 0);
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: