1103 Integer Factorization

    网上基本都是深搜的解法,一开始用背包做陷进去了,其实背包也可以做。
    建两个三维数组,三个维度分别为n,k,m(小于n的平方数总数,最大20)。
    第一个数组记录在前m个数中拿满k个数,并且和为n的情况下,fac和的最大值。如果无法满足上述情况,就是0。
    第二个数组记录如果拿第m个数,需要拿的个数。
    最后就根据第二个数组倒着输出结果就好了,就满足从大到小输出的条件了。

代码:

#include<iostream>
#include<functional>
#include<vector>
#include<algorithm>
using namespace std;

int n, k, p, m, n2;
int value[401][401][22]; //记录factor的和,不可行为0。三个位置对应n,k,m,m是小于n的平方数总数,最多20。
int res[401][401][22]; //记录可行情况下每个数字的次数
vector<int> items, ans;
int main()
{
	cin >> n >> k >> p;
	n2 = n;
	int item = 0;
	for (int i = 1; item <= n; i++) {
		items.push_back(item);
		item = pow(i, p);
	}
	m = items.size() - 1;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= k; ++j) {
			for (int x = 1; x <= m; ++x) {
				if (items[x] > i) {
					value[i][j][x] = value[i][j][x - 1];
				}
				else {
					int w = i - items[x], ct(j - 1), maxv(value[i][j][x - 1]), inc = x;
					for (; w >= 0 && ct >= 0 ; w -= items[x], ct--, inc+=x) {
						if (value[w][ct][x] || (!w && !ct)) {
							if (value[w][ct][x] + inc >= maxv) { //等于一定要包含,不然没法统计结果。
								res[i][j][x] = j - ct;
								maxv = value[w][ct][x] + inc;
							}
						}
					}
					value[i][j][x] = maxv;
				}
			}
		}
	}
	if (!value[n][k][m]) {
		printf("Impossible");
		return 0;
	}
	while (k) { //输出结果
		for (; m >= 1; --m) {
			if (res[n][k][m]) break;
		}
		int times = res[n][k][m];
		for (int x = 0; x < times; ++x) ans.push_back(m);
		k -= times;
		n -= items[m]* times;
		--m;
	}
	printf("%d = ", n2);
	for (int i = 0; i < ans.size(); ++i) {
		if (i != 0) printf(" + ");
		printf("%d^%d", ans[i], p);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值