一開始写的高位往低位递推,发现这样有些时候保证不了第四条要求。于是又開始写高位往低位的记忆化搜索,又发现传參什么的蛋疼的要死。然后又发现高位開始的记忆化搜索就是从低位往高位的递推呀,遂过之。

dp[i][j]记录在i位 且 余数为j时的最优解情况。

dp[i][j].next表示当前的最优解是由哪一种状态转移过来的。

代码又写锉了。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map> #pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 9999991 using namespace std; struct N
{
bool mark;
int ans,dig,next;
}dp[111][10000]; char s[110]; int mod1[110],mod2[110]; void Out(int site,int mod)
{
if(mod == -1)
return ;
printf("%d",dp[site][mod].dig);
Out(site+1,dp[site][mod].next); } int main()
{
int k,i,j,l; while(scanf("%s %d",s+1,&k) != EOF)
{
for(i = 1; s[i] != '\0'; ++i)
{
for(j = 0; j < k; ++j)
dp[i][j].mark = false;
} mod1[0] = 0,mod2[0] = 1%k; for(i = 1;s[i] != '\0'; ++i)
{
mod1[i] = (mod1[i-1]*10 + s[i]-'0')%k;
mod2[i] = (mod2[i-1]*10)%k;
} int site = strlen(s+1); for(i = 0 ;i <= 9 ; ++i)
{
if(dp[site][i%k].mark == false)
{
dp[site][i%k].mark = true;
dp[site][i%k].ans = (i == s[site]-'0' ? 0 : 1);
dp[site][i%k].dig = i;
dp[site][i%k].next = -1;
}
else
{
if((i == s[site]-'0' ? 0 : 1) < dp[site][i%k].ans)
{
dp[site][i%k].ans = (i == s[site]-'0' ? 0 : 1);
dp[site][i%k].dig = i;
}
else if((i == s[site]-'0' ? 0 : 1) == dp[site][i%k].ans && i <= dp[site][i%k].dig)
{
dp[site][i%k].dig = i;
}
}
} int mod;
int len = strlen(s+1); for(--site ; site >= 1 ; --site)
{
mod = 0;
for(i = (site == 1 ? 1 : 0);i <= 9; ++i)
{
for(j = 0;j < k; ++j)
{
if(dp[site+1][j].mark == true)
{
if(dp[site][(mod + i*mod2[len-site] + j)%k].mark == false)
{
dp[site][(mod + i*mod2[len-site] + j)%k].mark = true;
dp[site][(mod + i*mod2[len-site] + j)%k].ans = dp[site+1][j].ans+(s[site]-'0' == i ? 0 :1);
dp[site][(mod + i*mod2[len-site] + j)%k].dig = i;
dp[site][(mod + i*mod2[len-site] + j)%k].next = j;
}
else
{
if(dp[site+1][j].ans+(s[site]-'0' == i ? 0 :1) < dp[site][(mod + i*mod2[len-site] + j)%k].ans)
{
dp[site][(mod + i*mod2[len-site] + j)%k].ans = dp[site+1][j].ans+(s[site]-'0' == i ? 0 :1);
dp[site][(mod + i*mod2[len-site] + j)%k].dig = i;
dp[site][(mod + i*mod2[len-site] + j)%k].next = j;
}
else if(dp[site+1][j].ans+(s[site]-'0' == i ? 0 :1) == dp[site][(mod + i*mod2[len-site] + j)%k].ans && i < dp[site][(mod + i*mod2[len-site] + j)%k].dig)
{
dp[site][(mod + i*mod2[len-site] + j)%k].dig = i;
dp[site][(mod + i*mod2[len-site] + j)%k].next = j;
}
}
}
}
}
}
Out(1,0);
puts("");
// cout<<len<<endl;
// for(i = 1;i <= len; ++i)
// {
// for(j = 0;j < k; ++j)
// {
// if(dp[i][j].mark)
// printf("%2d ",dp[i][j].next);
// else
// printf(" ");
// }
// puts(" * ");
// }
//
// puts("");
//
// for(i = 1;i <= len; ++i)
// {
// for(j = 0;j < k; ++j)
// {
// if(dp[i][j].mark)
// printf("%2d ",dp[i][j].dig);
// else
// printf(" ");
// }
// puts(" * ");
// }
//
// puts("");
//
//
// for(i = 1;i <= len; ++i)
// {
// for(j = 0;j < k; ++j)
// {
// if(dp[i][j].mark)
// printf("%2d ",dp[i][j].ans);
// else
// printf(" ");
// }
// puts(" * ");
// } } return 0;
}

POJ 3373 Changing Digits 好蛋疼的DP的更多相关文章

  1. poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)

    http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS   Memory Limit: 65536K Total Submi ...

  2. POJ 3373 Changing Digits(DP)

    题目链接 记录路径的DP,看的别人的思路.自己写的也不好,时间居然2000+,中间的取余可以打个表,优化一下. 写的各种错,导致wa很多次,写了一下午,自己构造数据,终于发现了最后一个bug. dp[ ...

  3. POJ 3373 Changing Digits

    题目大意: 给出一个数n,求m,使得m的长度和n相等.能被k整除.有多个数符合条件输出与n在每位数字上改变次数最小的.改变次数同样的输出大小最小的.  共同拥有两种解法:DP解法,记忆化搜索的算法. ...

  4. POJ 3373 Changing Digits 记忆化搜索

    这道题我是看了别人的题解才做出来的.题意和题解分析见原文http://blog.csdn.net/lyy289065406/article/details/6698787 这里写一下自己对题目的理解. ...

  5. POJ 3249 Test for Job (拓扑排序+DP)

    POJ 3249 Test for Job (拓扑排序+DP) <题目链接> 题目大意: 给定一个有向图(图不一定连通),每个点都有点权(可能为负),让你求出从源点走向汇点的路径上的最大点 ...

  6. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  7. POJ 3254 Corn Fields(状压DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13732   Accepted: 7216 Desc ...

  8. POJ 3267:The Cow Lexicon(DP)

    http://poj.org/problem?id=3267 The Cow Lexicon Time Limit: 2000MS   Memory Limit: 65536K Total Submi ...

  9. POJ #1042 Gone Fishing - WA by a DP solution. TODO

    I used DP instead of Greedy. But got WA on PoJ, though it passed all web-searched cases. Maybe I hav ...

随机推荐

  1. NET中小型企业项目开发框架系列(一个)

    当时的前端,我们开发了基于Net一组结构sprint.NET+NHibernate+MVC+WCF+EasyUI等中小型企业级系统开发平台,如今把整个开发过程中的步步进展整理出来和大家分享,这个系列可 ...

  2. 1.cocos2dx 3.2环境结构

    1        所需软件 jdk-7u25-windows-i586.exe python-2.7.8.amd64.msi cocos2d-x-3.2.zip apache-ant-1.9.4.zi ...

  3. WINDOWS7,8和os x yosemite 10.10.1懒人版双系统安装教程

    安装过程 磁盘划分 懒人版如果不是整盘单系统或者双硬盘双系统安装我们需要在当前系统磁盘划分两块磁盘空间,一个用来做安装盘,一个作为系统盘. 我这里是单硬盘,想从最后一个盘符压缩出80GB的空来安装黑苹 ...

  4. qml动画控制器AnimationController

    AnimationController: 一般的动画是使用定时器来完毕的,可是AnimationController同意给定的动画,手动控制,能够通过控制她的progress属性来操作动画的进度. c ...

  5. Google免费的SVN服务器管理VS2010代码

    原文:Google免费的SVN服务器管理VS2010代码 前言 Google免费为我们提供了代码管理的SVN服务器.首先我这里用的Win7 64的电脑系统,用VS2010进行的代码开发.这里管理代码需 ...

  6. Java并发编程之ConcurrentHashMap(转)

    ConcurrentHashMap ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法.Concurrent ...

  7. jquery ui tab跳转

    1.tabs_iframe.jsp <%-- Document : tabs Created on : 2015-2-28, 14:44:02 Author : liyulin lyl01099 ...

  8. SQL Server中TempDB管理(版本存储区的一个example)

    原文:SQL Server中TempDB管理(版本存储区的一个example) 原文来自: http://blogs.msdn.com/b/sqlserverstorageengine/archive ...

  9. Android MotionEvent事故响应机制

    于android于.主要活动包括点击.按.拖累.滑动等操作,这些构成了Android事件响应,总体而言,,所有事件由例如以下三部分构成的基础: 按(action_down),搬家(action_mov ...

  10. 纯css3 轮播图 利用keyframes

    效果: 关键点:利用keyframes 原理:infinite 注意点:在处理关键帧动画的时候,注意处理好 总共花费的 animation-duration:time  与每帧延延迟的时间的交错:要让 ...