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 ...
随机推荐
- 读书时间《JavaScript高级程序设计》四:BOM,客户端检测
隔了一段时间,现在开始看第8章. 第8章:BOM BOM提供了很多对象,用于访问浏览器的功能.BOM的核心对象是window,它表示浏览器的一个实例. window对象是通过javascript访问浏 ...
- 【Android基础】单元测试的配置
1.在AndroidManifest清单文件中进行配置 <application android:allowBackup="true" android:debuggable= ...
- Visual Studio中开发
如何在Visual Studio中开发自己的代码生成器插件 Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代 ...
- D其他项目打电话AL工程EF Model
Based on your description and the error code, you will just need to ensure that your DataContext ...
- MongoDB日常保养
它引入了程序来进行维护管理工具 MongoDB的日常维护包含使用配置文件,设置訪问控制.Shell交互,系统监控和管理,数据库日常备份和恢复 启动和停止MongoDB 启动后能够通过数据库的IP加po ...
- OpenWrt wireless通过配置uci生效
[转载请注明出处:钱正柱 http://blog.csdn.net/qianguozheng/article/details/24412673] 配置无线 vi /etc/config/wireles ...
- Android在ListView滑动数据混乱
我相信做过Android应用程序开发或多或少都遇到了这个问题.或者是在ListView数据损坏幻灯片事件.要么GridView数据损坏幻灯片事件. 让我们来看看一个网友写的文章,个人感觉还不错的文章: ...
- JAVA 统计字符串中中文,英文,数字,空格的个数
面试题:输入一行字符,分别统计出其中英文字母.中文字符.空格.数字和其它字符的个数 可以根据各种字符在Unicode字符编码表中的区间来进行判断,如数字为'0'~'9'之间,英文字母为'a'~'z'或 ...
- 基于AVR128单纯Modbus协议实施
Modbus通信协议Modicon公司1979在发展中,适用于工业现场总线协议控制.Modbus通信系统包含芯片的节点,并与组合物可编程控制的公共传输线,它的目的是收集和监视多个节点的数据.Modbu ...
- C#
抽象类其中创建一个静态方法
</pre><pre name="code" class="csharp"><span style="font-size ...