[HDOJ5787]K-wolf Number(数位DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787

题意:求[L,R]区间内的数字,使得所有长度为k的子数列内所有数位都不同。

K<=5的所以可以直接记录到前k个数字的值是多少。dp(l,p1,p2,p3,p4)分别记录就可以了。

弱智了WA了好几发,因为k每次取值是不一样的,所以dp数组还是应当放在while里清空。

 #include <bits/stdc++.h>
using namespace std; typedef long long LL;
const int maxn = ;
int k;
int digit[maxn];
LL dp[maxn][][][][];
LL l, r; bool ok(int a, int b, int c, int d, int e) {
if(k == ) return e != d;
if(k == ) return e != d && e != c;
if(k == ) return e != d && e != c && e != b;
if(k == ) return e != d && e != c && e != b && e != a;
} LL dfs(int l, int p1, int p2, int p3, int p4, bool flag) {
if(l == ) return p4 != ;
if(!flag && ~dp[l][p1][p2][p3][p4]) return dp[l][p1][p2][p3][p4];
LL ret = ;
int pos = flag ? digit[l] : ;
for(int i = ; i <= pos; i++) {
if(i == && p4 == ) ret += dfs(l-,,,,,flag&&(i==pos));
else if(ok(p1,p2,p3,p4,i)) ret += dfs(l-,p2,p3,p4,i,flag&&(i==pos));
}
if(!flag) dp[l][p1][p2][p3][p4] = ret;
return ret;
} LL f(LL x) {
if(l <= ) return ;
int pos = ;
while(x) {
digit[++pos] = x % ;
x /= ;
}
return dfs(pos,,,,,true);
} int main() {
// freopen("in", "r", stdin);
while(~scanf("%I64d%I64d%d",&l,&r,&k)) {
memset(dp, -, sizeof(dp));
printf("%I64d\n", f(r)-f(l-));
}
return ;
}
上一篇:spring3: 延迟初始化Bean


下一篇:ECNU1101-Dinic