一名苦逼的OIer,想成为ACMer

Iowa_Battleship

HDOJ4734 F(x)

原题链接

数位\(DP\)继续套记搜模板
定义\(f[pos][now]\)\(pos\)是枚举到的位数,\(now\)\(A\)的权值减去当前枚举的数的权值,即剩余权值大小。
然后就是记搜模板的事。

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 10;
const int M = 5010;
int f[N][M], a[N], F;
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
int dfs(int pos, int nw, int lm)
{
	if (pos < 0)
		return nw <= F;
	if (nw > F)
		return 0;
	if (!lm && f[pos][F - nw] > -1)
		return f[pos][F - nw];
	int i, k = lm ? a[pos] : 9, s = 0;
	for (i = 0; i <= k; i++)
		s += dfs(pos - 1, nw + i * (1 << pos), lm && i == a[pos]);
	if (!lm)
		return f[pos][F - nw] = s;
	return s;
}
int calc(int x)
{
	int l = 0;
	do
	{
		a[l++] = x % 10;
		x /= 10;
	} while (x > 0);
	return dfs(l - 1, 0, 1);
}
void evaf(int x)
{
	int k = 0;
	for (F = 0; x > 0; k++, x /= 10)
		F += x % 10 * (1 << k);
}
int main()
{
	int i, n, m, t;
	t = re();
	memset(f, -1, sizeof(f));
	for (i = 1; i <= t; i++)
	{
		n = re();
		m = re();
		evaf(n);
		printf("Case #%d: %d\n", i, calc(m));
	}
	return 0;
}

posted on 2018-09-26 19:57  Iowa_Battleship  阅读(175)  评论(0编辑  收藏  举报

导航