HDU-3652 B-number (数位dp)
来源:互联网 发布:喜马拉雅fm无网络连接 编辑:程序博客网 时间:2024/06/05 17:44
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=3652题意:
计算区间内是13的倍数并且包含13的数的个数。思路:
数位dp,既要包含13又要是13的倍数,所以有2个状态。具体见代码注释。
代码:
预处理写法:
//kopyh#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define MOD 1000000007#define EPS 1e-6#define N 21using namespace std;int n,m,sum,res,flag;//dp[i][j][k]第i位余数为j的是否包含13的数的个数,k==0不包含,k==1首位为3,k==2包含13//a[i] 1ei的余数int dp[N][13][3],a[N];void init(){//计算每个位数的余数 a[0]=1; for(int i=1;i<N;i++) a[i] = a[i-1]*10%13; memset(dp,0,sizeof(dp)); dp[0][0][0] = 1; for(int i=1;i<N;i++)//迭代位数 for(int j=0;j<13;j++)//枚举余数 { for(int k=0;k<10;k++)//枚举首位数字 {dp[i][(j+a[i-1]*k)%13][0]+=dp[i-1][j][0];dp[i][(j+a[i-1]*k)%13][2]+=dp[i-1][j][2];}//记录首位为3的个数dp[i][(j+a[i-1]*3)%13][1] += dp[i-1][j][0];//把新包含13的个数调整到dp[i][][2]中 dp[i][(j+a[i-1])%13][0] -= dp[i-1][j][1]; dp[i][(j+a[i-1])%13][2] += dp[i-1][j][1]; }}int solve(int x){//取出数位 int dig[N],len=0; while(x)dig[len++]=x%10,x/=10; dig[len]=0; int flag=0,ans=0,mod=0;//从高位到低位枚举每一位数 for(int i=len-1;i>=0;i--) {//枚举当前位为j,得到前面的余数为(mod+j*a[i])%13,//后面位数中余数是(13-(mod+j*a[i])%13)%13的个数都是答案。 for(int j=0;j<dig[i];j++) ans+=dp[i][(13-(mod+j*a[i])%13)%13][2]; if(flag) {//前面已经有了13,只要是前面和后面所有位数的余数为0的就是答案。 for(int j=0;j<dig[i];j++) ans+=dp[i][(13-(mod+j*a[i])%13)%13][0]; } else {//首位是3的余数和为0就是答案。 if(dig[i+1]==1&&dig[i]>3) ans+=dp[i+1][(13-mod)%13][1];//取当前位为1后面首位为3的是答案。 if(dig[i]>1) ans+=dp[i][(13-(mod+a[i])%13)%13][1]; }//已经出现过13,标记。 if(dig[i+1]==1&&dig[i]==3)flag=1; mod=(mod+dig[i]*a[i])%13; } return ans;}int main(){ int i,j,k,kk,cas,T,t,x,y,z; init(); while(scanf("%d",&n)!=EOF) printf("%d\n",solve(n+1)); return 0;}
深搜写法:
//kopyh#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define MOD 1000000007#define EPS 1e-6#define N 11using namespace std;int n,m,sum,res,flag;int dp[N][13][3],dig[N];//len:当前位,mod:前面留下的余数大小,k:前面是否出现13,flag:前面每一位是否都是上限。int dfs(int len, int mod, int k, int flag){ if(len<=0)return (!mod && k==2); //通过dp优化 if(!flag && dp[len][mod][k]!=-1)return dp[len][mod][k]; //通过是否为上限确定当前位可取的最大值 int num = flag?dig[len]:9; int ans=0; for(int i=0;i<=num;i++) { int modt = (mod*10+i)%13; //确定是否已出现13 int kt; if(k==2 || k==1&&i==3)kt=2; else if(i==1)kt=1; else kt=0; ans+=dfs(len-1,modt,kt,flag&&num==i); } if(!flag)dp[len][mod][k] = ans; return ans;}int main(){ int i,j,k,kk,cas,T,t,x,y,z; while(scanf("%d",&n)!=EOF) { memset(dp,-1,sizeof(dp)); sum=0; while(n)dig[++sum]=n%10,n/=10; printf("%d\n",dfs(sum,0,0,1)); } return 0;}
0 0
- HDU 3652--B-number(数位dp)
- HDU 3652 B-number(数位DP)
- [HDU 3652]B-number[数位DP]
- hdu 3652 B-number (数位DP)
- hdu 3652 B-number(数位DP)
- HDU:3652 B-number(数位DP)
- HDU-3652 B-number 数位DP
- HDU 3652 B-number(数位dp模版)
- hdu 3652 B-number(数位dp)
- [数位dp] hdu 3652 B-number
- 【HDU】3652 B-number 数位DP
- hdu 3652 B-number(数位dp)
- HDU 3652 B-number (数位DP)
- HDU 3652 B-number(数位DP)
- HDU 3652 B-number(数位DP)
- hdu 3652 B-number (数位DP)
- 【数位DP】 HDU 3652 B-number
- HDU 3652 B-number(数位DP)
- sql server实现分页
- javascript线程解释(setTimeout,setInterval你不知道的事)
- python2.7:创建修改删除目录
- jsp中的contentType与pageEncoding的区别和作用http://www.cnblogs.com/freewater/archive/2011/12/21/2295827.html
- HTTP 错误 404.17 - Not Found 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。
- HDU-3652 B-number (数位dp)
- onCreate方法中调用PopupWindow的错误
- 24.Android Studio报错:non-zero exit value 2
- ShareSDK Android接入cocos2d-X lua
- MySQL权限篇之EVENT及EXECUTE
- 埃拉托色尼(Eratosthenes)筛法
- Xcode7.3编译unity导出工程出现 Error "unknown type name __declspec" after Xcode 7.3 upgrade
- ViewPager如何阻止其滑动和一次切换多页闪烁的问题
- a definer ('root'@'%') does not exist