您的位置:首页 > 其它

hdu 5787 K-wolf Number (数位DP )

2016-08-03 16:51 363 查看
Problem Description

Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation of x is pairwised different.

Given (L,R,K), please count how many K-wolf numbers in range of [L,R].

 

Input

The input contains multiple test cases. There are about 10 test cases.

Each test case contains three integers L, R and K.

1≤L≤R≤1e18
2≤K≤5

 

Output

For each test case output a line contains an integer.

 

Sample Input

1 1 2
20 100 5

 

Sample Output

1
72

 
(1)前导零的处理

代码1

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <bitset>

#define LL long long

#pragma comment(linker, "/STACK:102400000,102400000")

using namespace std;

const double eps = 1e-9;
const int inf = 0x3f3f3f3f;

int n,m;
LL l,r;
int k;

map<vector<int>,LL> dp[20];

int digit[29];
int tot=0;

bool ok(const vector<int> & ve)
{
int last = ve[k-1];
for(int i=0; i<k-1; i++)
{
if(last == ve[i])
return false;
}

return true;
}

LL dfs(int pos,vector<int> vec,bool ismax,bool iszero)
{
if(pos==0)
{
return 1LL;
}

if(!ismax && dp[pos].count(vec)) return dp[pos][vec];

LL res=0;

int ed = ismax? digit[pos] : 9;

vector<int> nt;
for(int i=1; i<vec.size(); i++)
{
if(!iszero)
nt.push_back(vec[i]);
else nt.push_back(-i);
}

for(int i=0; i<=ed; i++)
{
nt.push_back(i);

if(ok(nt))
res += dfs(pos-1,nt,ismax && i==ed,iszero && i==0);
nt.pop_back();
}

return ismax ? res : dp[pos][vec] = res;

}

LL solve(LL x)
{
tot=0;
while(x)
{
digit[++tot] = x%10;
x /=10;
}

vector<int> vec;
for(int i=1; i<=k; i++) vec.push_back(-i);

return dfs(tot,vec,true,true);

}

int main()
{

for(int i=0; i<20; i++) dp[i].clear();

while(scanf("%I64d%I64d%d",&l,&r,&k)!=EOF)
{
printf("%I64d\n",solve(r) - solve(l-1));
}
return 0;
}

代码2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#define bug(x) cout<<#x<<" = "<<x<<endl;
using namespace std;

const int maxn = 20;
typedef __int64 LL;

LL l,r;
int k;

int tot=0;
int digit[20];

LL dp[20][110000];
LL mod;
int uu[10];

bool can(LL num,int len)
{
int t;
memset(uu,0,sizeof(uu));
for(int i=0;i<len;i++)
{
t = num%10;
num /=10;
++uu[t];
if(uu[t]>=2) return false;
}
return true;
}

LL dfs(int pos,LL num,int len,int flag)
{
if(pos<=0)
{
return 1;
}

if(flag && dp[pos][num]!=-1) return dp[pos][num];

int la = flag ? 9 : digit[pos];

LL ans=0;
LL cc;

for(int i=0;i<=la;i++)
{
cc = (num*10 + i)%mod;

if( !can(cc,min(k,len+1)) ) continue;

if(len==0)
{
if(i==0)
ans += dfs(pos-1,cc,len, flag||i!=la);
else ans += dfs(pos-1,cc,min(k,len+1),flag||i!=la);
}else{
ans += dfs(pos-1,cc,min(k,len+1),flag||i!=la);
}
}
if(flag)
dp[pos][num]=ans;
return ans;
}

LL solve(LL num)
{
tot=0;
while(num){digit[++tot]= num%10;num/=10;}

return dfs(tot,0,0,0);
}

int main()
{

while(scanf("%I64d%I64d%d",&l,&r,&k)!=EOF)
{
memset(dp,-1,sizeof(dp));
mod=1;
for(int i=1;i<=k;i++)
mod *=10;
printf("%I64d\n", solve(r)-solve(l-1) );
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: