砝码称重、包子凑数(DP)

砝码沉重“蓝桥杯”练习系统 (lanqiao.cn)

解析:01背包。集合dp[i][j]:前i个砝码能表示的重量j,属性:bool;

状态转移:不选当前第i个砝码:dp[i][j];选当前砝码来增加重量:dp[i][j+a];选当前砝码减少重量:dp[i][abs(j-a)](可能为负,补个绝对值)

//dp[i][j]表示前i个砝码可以表示重量j
//如果dp[i-1][j]为真,dp[i][j]=dp[i][j-a[i]]=dp[i][j+a[i]]=dp[i][a[i]-j]=1
//这是01背包(我认为不能用一维),可以选择先放一个大砝码,然后加减小的,这里无法控制,所以只能用二维数组控制砝码数量为0或1个
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int s,n,dp[105][100005];//前i个砝码可以表示的重量
 
int main() {
	cin>>n;
	dp[0][0]=1;//初始化
	for(int i=1; i<=n; i++) {//砝码
		int a;
		cin>>a;
		for(int j=0; j<=100000; j++)//重量
			if(dp[i-1][j]) {
				dp[i][j+a]=dp[i][j]=dp[i][abs(a-j)]=1;
			}
	}
	for(int j=1; j<100005; j++)
		if(dp[n][j]>0) s++;
	cout<<s;
	return 0;
}

包子凑数“蓝桥杯”练习系统 (lanqiao.cn)

解析:

DP。下面两个代码都是DP的实现方式,不过有一点点差距(本质上没区别)。

分析: 这是一个完全背包问题。直接可以用1维来做,只要标记这个重量是否能表示即可,和上题差不多(标记方式)。dp[i]表示质量为i时能否被表示,属性是bool,方程:dp[i] |= dp[i + a[j]]。

如果这些数的公约数是1,那么就只有有限个不会被表示,如果不是1则有无限个不能被表示,这里需要计算一下。

数据量是100*100,所以我们的maxn开到1e4即可

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long LL;
int n;
int dp[10005],a[105];

int gcd(int a,int b) {
	return b==0?a:gcd(b,a%b);
}

int main() {
	int d=0;
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		d=gcd(d,a[i]);
	}
	if(d!=1) cout<<"INF"<<endl;
	else {
		dp[0]=1;
		for(int i=1; i<=n; i++) {
			for(int j=0; j<10005; j++) {
				if(dp[j]) dp[j+a[i]]=1;
			}
		}
		int s=0;
		for(int i=1; i<10005; i++)
			if(!dp[i]) s++;
		cout<<s;
	}
	return 0;
}
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long LL;
int n;
int dp[10005],a[105];

int gcd(int a,int b) {
	return b==0?a:gcd(b,a%b);
}

int main() {
	int d=0;
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		d=gcd(d,a[i]);
	}
	if(d!=1) cout<<"INF"<<endl;
	else {
		dp[0]=1;
		for(int i=1; i<=n; i++) {
			for(int j=a[i]; j<10005; j++) {//这是一个完全背包的模型(从小到大)
				dp[j] |= dp[j-a[i]];//或运算,相当于if(dp[j-a[i]]) dp[j]=1,也就是上面那个码
			}
		}
		int s=0;
		for(int i=1; i<10005; i++)
			if(!dp[i]) s++;
		cout<<s;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_61017400/article/details/123924157
今日推荐