[蓝桥杯 2017 省 AB] 包子凑数(方案dp)

        通过题目描述,我们可以发现,如果包子数目的最大公约数大于1,说明会有无限多个数字无法进行拼凑。因为对于某个无法拼凑的数字,可以乘以最大公约数得到另一个无法拼凑的数字,也就是说如果最大公约数不是1,就会有无穷个无法拼凑的数字,对于有限次的情况,我们可以通过方案dp来存储如果dp[i]可以进行拼凑,说明dp[i + a[i]]同样也可以进行拼凑,根据这个方案,我们就能寻找出答案

上代码

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 1e6 + 10;
bool dp[N];//dp[i]表示数量为i能否拼凑出来

int main(void)
{
	int n; cin >> n;
	int *a = new int[n + 10];
	int Gcd = 0;//求出所有数字的最大公约数,如果最大公约数大于1,就意味着有无限个数字拼凑不出来 
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		Gcd = __gcd(a[i], Gcd);
	}
	if(Gcd > 1){
		cout << "INF" << endl;
		return 0;//如果公约数大于1说明有无数个数字拼凑不出来,直接输出INF并返回0 
	} 
	
	dp[0] = 1;//初始化动态数组 
	for(int i = 1; i <= n; i++){//从第一种包子开始遍历,列出其能凑出的所有数量 
		for(int j = 0; j <= 1e4; j++){
			if(dp[j]) dp[j + a[i]] = 1;
		}
	} 
	
	int ans = 0;
	for(int i = 1; i <= 1e4; i++){
		if(!dp[i]) ans++;
	}
	
	cout << ans << endl;
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值