#include
#include
#include
using namespace std;
int visited[5][20][9009];// 访问情况
int dp[5][20][9009]; // M N num num即M-1位的数字
int num_2[7]= {2,3,5,7,11,13,17};
int num_3[9]= {2,3,5,7,11,13,17,19,23};
int num_4[11]= {2,3,5,7,11,13,17,19,23,29,31}; //存储素数
int N,M;
int delete_head(int num,int m) //去掉当前数字的首个数字
{
int ans;
if (m==2) return 0;
if (m==3) ans=num-num/10*10;
if (m==4) ans=num-num/100*100;
return ans;
}
int divide_num(int num)
{
int ans=0;
while (num>0)
{
ans+=num;
num=num/10;
}
return ans;
}
int select_num(int k,int sum,int m)
{
if (m==2)
{
for (int i=0; i<7; i++) if (k+divide_num(sum)==num_2[i]) return 1;
return 0;
}
if (m==3)
{
for (int i=0; i<9; i++)
if (k+divide_num(sum)==num_3[i])
{
return 1;
}
return 0;
}
if (m==4)
{
for (int i=0; i<11; i++) if (k+divide_num(sum)==num_4[i]) return 1;
return 0;
}
}
void work(int m,int n,int num)
{
if (n==0) // n=0直接处理
{
visited[m][n][num]=1;
dp[m][n][num]=1;
}
else
{
if (!visited[m][n][num])
{
visited[m][n][num]=1;
for (int k=0; k<=9; k++)
{
if (select_num(k,num,m))
{
int next=delete_head(num,m)*10+k; //next是num的下个状态(去头加尾)
if (!visited[m][n-1][next])
{
work(m,n-1,next);
}
dp[m][n][num]+=dp[m][n-1][next];
}
}
}
}
}
int main()
{
memset(visited,0,sizeof(visited));
memset(dp,0,sizeof(dp));
scanf("%d %d",&N,&M);
if (M==1)
{
int ans=1;
while (N>0)
{
ans*=4;
N--;
}
printf("%d\n",ans);
}
if (M==2)
{
int ans=0;
for (int i=0; i<=9; i++)
{
int num=i;
work(M,N-1,num);
ans+=dp[M][N-1][num];
}
printf("%d\n",ans);
}
if (M==3)
{
int ans=0;
for (int i=0; i<=9; i++)
for (int k=0; k<=9; k++)
{
int num=i*10+k;
work(M,N-2,num);
ans+=dp[M][N-2][num];
}
printf("%d\n",ans);
}
if (M==4)
{
int ans=0;
for (int i=0; i<=9; i++)
for (int k=0; k<=9; k++)
for (int x=0; x<=9; x++)
{
int num=i*100+k*10+x;
work(M,N-3,num);
ans+=dp[M][N-3][num];
}
printf("%d\n",ans);
}
return 0;
}

  

小明的密码由N(1<=N<=12)个数字构成,每个数字都可以是0至9中任意一个数字,但小明的密码还有 一个特点就是密码中连续的M(1<=M<=4)个数字的和是质数,现给定M和N,求满足条件的密码共有多少 个? 输入格式 第1行是T,case数量,此后T行,每行两个数,N和M 输出格式 每个case输出一个满足条件的密码总数 
输入样例 
1 1 
2 1 
输出样例 
16 
作者 admin
第一次做多维DP,虽然才做到第三个维度,感觉已经够狠的题目还可以出的更复杂,比如M更大的时候我还没想过怎么操作,暂时做到三维DP,主要是做第三维的时候遇到困难,第一次做的时候把前M-1位的数字和求出来做参数,没想到维度混淆了,还是只能用M-1做真整数,这样如果M稍微大一点,我可能都要做高精度了,而且内存也不宽裕,继续努力想其他解法吧
 #include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
int visited[][][];// 访问情况
int dp[][][]; // M N num num即M-1位的数字
int num_2[]= {,,,,,,};
int num_3[]= {,,,,,,,,};
int num_4[]= {,,,,,,,,,,}; //存储素数
int N,M;
int delete_head(int num,int m) //去掉当前数字的首个数字
{
int ans;
if (m==) return ;
if (m==) ans=num-num/*;
if (m==) ans=num-num/*;
return ans;
}
int divide_num(int num)
{
int ans=;
while (num>)
{
ans+=num;
num=num/;
}
return ans;
}
int select_num(int k,int sum,int m)
{
if (m==)
{
for (int i=; i<; i++) if (k+divide_num(sum)==num_2[i]) return ;
return ;
}
if (m==)
{
for (int i=; i<; i++)
if (k+divide_num(sum)==num_3[i])
{
return ;
}
return ;
}
if (m==)
{
for (int i=; i<; i++) if (k+divide_num(sum)==num_4[i]) return ;
return ;
}
}
void work(int m,int n,int num)
{
if (n==) // n=0直接处理
{
visited[m][n][num]=;
dp[m][n][num]=;
}
else
{
if (!visited[m][n][num])
{
visited[m][n][num]=;
for (int k=; k<=; k++)
{
if (select_num(k,num,m))
{
int next=delete_head(num,m)*+k; //next是num的下个状态(去头加尾)
if (!visited[m][n-][next])
{
work(m,n-,next);
}
dp[m][n][num]+=dp[m][n-][next];
}
}
}
}
}
int main()
{
memset(visited,,sizeof(visited));
memset(dp,,sizeof(dp));
scanf("%d %d",&N,&M);
if (M==)
{
int ans=;
while (N>)
{
ans*=;
N--;
}
printf("%d\n",ans);
}
if (M==)
{
int ans=;
for (int i=; i<=; i++)
{
int num=i;
work(M,N-,num);
ans+=dp[M][N-][num];
}
printf("%d\n",ans);
}
if (M==)
{
int ans=;
for (int i=; i<=; i++)
for (int k=; k<=; k++)
{
int num=i*+k;
work(M,N-,num);
ans+=dp[M][N-][num];
}
printf("%d\n",ans);
}
if (M==)
{
int ans=;
for (int i=; i<=; i++)
for (int k=; k<=; k++)
for (int x=; x<=; x++)
{
int num=i*+k*+x;
work(M,N-,num);
ans+=dp[M][N-][num];
}
printf("%d\n",ans);
}
return ;
}
												

小明的密码-初级DP解法的更多相关文章

  1. scauoj 18025 小明的密码 数位DP

    18025 小明的密码 时间限制:4000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description 小明的密码由N(1<=N& ...

  2. hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  3. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  4. HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)

    小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  5. HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)

    Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则:  1.如果小明 ...

  6. 2018.07.08 hdu4521 小明系列问题——小明序列(线段树+简单dp)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Proble ...

  7. HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)

    小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  8. HDU4511 小明系列故事——女友的考验 —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-4511 小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memor ...

  9. FZU 2186 小明的迷宫 【压状dp】

    Problem Description 小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫.因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷 ...

随机推荐

  1. 理解HTML语义化

    1.什么是HTML语义化? <基本上都是围绕着几个主要的标签,像标题(H1~H6).列表(li).强调(strong em)等等> 根据内容的结构化(内容语义化),选择合适的标签(代码语义 ...

  2. POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9276   Accepted: 3924 ...

  3. mac 终端 svn 命令

      1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录)   例如:svn checkout svn://192.168.1.1/pro/domain  ...

  4. [LeetCode] Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  5. [LeetCode] Single Number III 单独的数字之三

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  6. [LeetCode] Median of Two Sorted Arrays 两个有序数组的中位数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  7. 如何在Microsoft Edge浏览器中添加一个Hello World插件

    注:本文提到的代码示例下载地址> How to add a Hello World extension to Microsoft Edge Microsoft Edge 随着Win 10一起推出 ...

  8. maven配置和下载

    下载链接:http://maven.apache.org/docs/ 以maven3.0.4为例,eclipse以kepler为例 环境变量的配置 1.系统变量-新建-变量名:MAVEN_HOME-变 ...

  9. 用libcurl 登录网站

    libcurl 可以发送和接收HTTP消息,因此可以发送用户名.密码和验证码来登录网站,网上有不少这方面的内容,但不甚完整,我摸索了两天,将其中要点记录下来. 基本步骤 正常访问登录页面,访问时,设置 ...

  10. WebAPI IIS PUT和DELETE请求失败 405

    IIS拒绝PUT和DELETE请求是由于IIS为网站默认注册的一个名为WebDAVModule的自定义HttpModule导致的,如果我们的站点不需要提供针对WebDAV的支持,解决这个问题最为直接的 ...