POJ 3373 Changing Digits 好蛋疼的DP
一開始写的高位往低位递推,发现这样有些时候保证不了第四条要求。于是又開始写高位往低位的记忆化搜索,又发现传參什么的蛋疼的要死。然后又发现高位開始的记忆化搜索就是从低位往高位的递推呀,遂过之。
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的更多相关文章
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS Memory Limit: 65536K Total Submi ...
- POJ 3373 Changing Digits(DP)
题目链接 记录路径的DP,看的别人的思路.自己写的也不好,时间居然2000+,中间的取余可以打个表,优化一下. 写的各种错,导致wa很多次,写了一下午,自己构造数据,终于发现了最后一个bug. dp[ ...
- POJ 3373 Changing Digits
题目大意: 给出一个数n,求m,使得m的长度和n相等.能被k整除.有多个数符合条件输出与n在每位数字上改变次数最小的.改变次数同样的输出大小最小的. 共同拥有两种解法:DP解法,记忆化搜索的算法. ...
- POJ 3373 Changing Digits 记忆化搜索
这道题我是看了别人的题解才做出来的.题意和题解分析见原文http://blog.csdn.net/lyy289065406/article/details/6698787 这里写一下自己对题目的理解. ...
- POJ 3249 Test for Job (拓扑排序+DP)
POJ 3249 Test for Job (拓扑排序+DP) <题目链接> 题目大意: 给定一个有向图(图不一定连通),每个点都有点权(可能为负),让你求出从源点走向汇点的路径上的最大点 ...
- POJ 1185 炮兵阵地(状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26426 Accepted: 10185 Descriptio ...
- POJ 3254 Corn Fields(状压DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13732 Accepted: 7216 Desc ...
- POJ 3267:The Cow Lexicon(DP)
http://poj.org/problem?id=3267 The Cow Lexicon Time Limit: 2000MS Memory Limit: 65536K Total Submi ...
- 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 ...
随机推荐
- CodeForces 484A Bits
意甲冠军: 10000询价 每次查询输入L和R(10^18) 在区间的二进制输出指示1大多数数字 1个数同样输出最小的 思路: YY一下 认为后几位全是1的时候能保证1的个数多 那么怎样构造 ...
- 【Android基础】listview控件的使用(4)-----自定义布局的listview的使用
前面我介绍了listview控件的不同用法,但是这些用法在实际的开发项目中是不足以满足需求的,因为前面的几种用法只能简单的显示文本信息,而且布局都比较单一,很难做出复杂的结果,在实际的开发项目中,90 ...
- Java中判断字符串是否为数字的五种方法 (转)
推荐使用第二个方法,速度最快. 方法一:用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str.length( ...
- Swift1_关闭
// main.swift // swift1_关闭 // Created by beyond on 15/6/12. // Copyright (c) 2015年 beyond.com All ri ...
- mac提升yosemite后php 扩展修复
mac升级之后 php 正积极提升自己,导致php环境破坏 所以 例如有以下几点需要修复 1. sudo ln -s /Applications/Xcode.app/Contents/Develope ...
- POJ2195 Going Home 【最小费用流】+【最佳匹配图二部】
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18169 Accepted: 9268 Descr ...
- 打印到类阵列的给定序列的所有排列的n皇后问题
题目例如以下:Given a collection of numbers, return all possible permutations. For example, [1,2,3] have th ...
- [SignalR]一个简单的聊天室
原文:[SignalR]一个简单的聊天室 1.说明 开发环境:Microsoft Visual Studio 2010 以及需要安装NuGet. 2.添加SignalR所需要的类库以及脚本文件: 3. ...
- extjs_09_定义自己的页面组件
1.项目截图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWRhbV93enM=/font/5a6L5L2T/fontsize/400/fill/I0J ...
- Java工程(3)——但从谈论用户的角度UI图案
前言: 海南项目宣告竣工,验收之日,除部分代码有待优化外,亟待改进的就是界面. 米老师说:连你都忍不住去拖下滚动栏,你还指望用户用的舒坦吗? 顿悟: 业务.功能也许是软件的核心,技术也许是软件的精髓. ...