POJ 3373 Changing Digits(記錄路徑的dp)
很長時間之前看的一道題目,一直以為是搜尋。結果發現是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;
}
相關文章
- POJ 1141 Brackets Sequence(記錄路徑的dp)Racket
- 【基礎dp路徑記錄】HDU 1160 FatMouse's Speed
- Codeforces 453B Little Pony and Harmony Chest:狀壓dp【記錄轉移路徑】
- URAL 1658. Sum of Digits(簡單dp)Git
- wordpress 記錄php-error.log路徑PHPError
- 一類哈密頓路徑/迴路為背景的狀壓dp
- POJ1849Two[DP|樹的直徑](擴充套件HDU4003待辦)套件
- POJ1745Divisibility(dp)
- POJ2955 Brackets (區間DP)Racket
- JAVA 取得當前目錄的路徑/Servlet/class/檔案路徑/web路徑/url地址JavaServletWeb
- poj 1180 dp的斜率優化優化
- POJ 2486 Apple Tree(樹形dp)APP
- POJ 1925 Spiderman(線性dp)IDE
- POJ 3744 概率dp+矩陣矩陣
- 【C#學習筆記】瀏覽目錄得到路徑C#筆記
- dp 套 dp(dp of dp)小記
- 計數 dp 做題記錄(日更)
- 【筆記】DP最佳化技巧目錄筆記
- POJ1160 Post Office[序列DP]
- 【dp】POJ 1015 Jury CompromisePromise
- POJ 3249-Test for Job(拓撲排序&&DP)排序
- POJ 3107 Godfather(樹形dp)Go
- POJ 3017 單調佇列dp佇列
- POJ 3691 DNA repair (AC自動機 + dp)AI
- 【MFC】BROWSEINFO設定路徑,支援記憶上次路徑
- Java獲取WEB目錄路徑JavaWeb
- Qt 程式獲取程式所在路徑、使用者目錄路徑、臨時資料夾等特殊路徑的方法QT
- 【樹形dp】poj 1947 Rebuilding RoadsRebuild
- POJ 1664 放蘋果 (基礎組合dp)蘋果
- POJ 2955-Brackets(括號匹配-區間DP)Racket
- java獲取硬碟根目錄的本地路徑Java硬碟
- poj 3764 最長異或路徑(二進位制trie樹)
- poj1179 區間dp(記憶化搜尋寫法)有巨坑!
- POJ3107Godfather[樹形DP 樹的重心]Go
- POJ 1947 Rebuilding Roads(基礎的樹形dp)Rebuild
- JavaScript 獲取目錄絕對路徑JavaScript
- 2023 5月 dp做題記錄
- 2023 6月 dp做題記錄