UVa 10400 - Game Show Math

題目:已知一串數字,在數字直接添加四則運算(+-*/),優先級為左側優先,

            求是否能是的計算的結果為題目給定的數字(除法要餘數為零才能進行)。

分析:動態規劃、dp。利用dp從前向後地推。

            每次將當前所有可行解與下一個數字進行四種則運算,結果在範圍內即為新的可行解。

說明:好久沒做過dp了╮(╯▽╰)╭。

#include <cstring>
#include <cstdio>

#define formap(x) ((x)+32000)
#define revmap(x) ((x)-32000)
#define range(L, x, R) ((x) >= L && (x) <= R)

int  f[101][64004], p[101][64004], value[101];
char o[101][64004];

int save(int id, int v, int parent, char operat)
{
	f[id][v] = 1;
	p[id][v] = parent;
	o[id][v] = operat;
}

int output(int id, int v)
{
	if (id > 1) {
		output(id-1, p[id][v]);
		printf("%c%d",o[id][v],value[id]);
	}else {
		printf("%d",value[id]);
	}
}

int main()
{
	int n, m, ans;
	while (~scanf("%d",&n)) 
	while (n --) {
		scanf("%d",&m);
		for (int i = 1; i <= m; ++ i) {
			scanf("%d",&value[i]);
		}
		scanf("%d",&ans);
		
		memset(f, 0, sizeof(f));
		f[1][formap(value[1])] = 1;
		for (int i = 2; i <= m; ++ i) {
			for (int j = 0; j <= 64000; ++ j) {
				if (!f[i-1][j]) {
					continue;
				}
				if (range(-32000, revmap(j)+value[i], 32000)) {
					save(i, formap(revmap(j)+value[i]), j, '+');
				}
				if (range(-32000, revmap(j)-value[i], 32000)) {
					save(i, formap(revmap(j)-value[i]), j, '-');
				}
				if (range(-32000, revmap(j)*value[i], 32000)) {
					save(i, formap(revmap(j)*value[i]), j, '*');
				}
				if (revmap(j)%value[i]) {
					continue;
				}
				if (range(-32000, revmap(j)/value[i], 32000)) {
					save(i, formap(revmap(j)/value[i]), j, '/');
				}
			}
		}
		if (f[m][formap(ans)]) {
			output(m, formap(ans));
			printf("=%d\n",ans);
		}else {
			puts("NO EXPRESSION");
		}
	} 
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值