您的位置:首页 > 其它

spoj Balanced Numbers(数位dp)

2015-08-09 10:28 495 查看
一个数字是Balanced Numbers,当且仅当组成这个数字的数,奇数出现偶数次,偶数出现奇数次

一下子就相到了三进制状压,数组开小了,一直wa,都不报re,

使用记忆化搜索,dp[i][s] 表示长度为i,状态为s,时,满足条件的balance number的个数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef  long long LL;
const int INF = 1<<30;
/*

*/
int num[30];
LL dp[30][60000];

int getNum(int sta)
{
int tmp1, tmp2;
for (int i = 0; i <= 9; ++i)
{
tmp1 = i &1;
tmp2 = sta % 3;
if (tmp1==0 && tmp2==2)//偶数出现了偶数次
return 0;
if (tmp1 == 1 && tmp2 == 1)//奇数出现了奇数次
return 0;
sta /= 3;
}
return 1;
}

int getSta(int x, int sta)
{
int val = 1;
int newSta = sta;
for (int i = 0; i < x; ++i)
{
val *= 3;
sta /= 3;
}
int times = sta % 3;
if (times == 0 || times == 1)
return newSta + val;
else
return newSta -  val;
}
LL dfs(int pos, int sta, bool zero, bool flag)
{
if (pos == 0) return getNum(sta);
if (!flag && dp[pos][sta] != -1) return dp[pos][sta];
int end = flag ?  num[pos] : 9;
LL ans = 0;
for (int i = 0; i <= end; ++i)
ans += dfs(pos - 1, (zero&&i==0)?0:getSta(i, sta),zero&&i==0 ,flag&&i == end);
if (!flag)
dp[pos][sta] = ans;
return ans;
}
LL calc(LL n)
{
int len = 0;
while (n)
{
num[++len] = n % 10;
n /= 10;
}
return dfs(len, 0, true, true);
}
int main()
{
memset(dp, -1, sizeof(dp));
int t;
LL l, r;
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &l, &r);
printf("%lld\n", calc(r) - calc(l - 1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: