蓝桥杯2021年第十二届省赛真题-砝码称重

题目链接

思路

d p [ i ] [ j ] = 1 / 0 dp[i][j] =1/0 dp[i][j]=1/0 : 表示前i个砝码能够凑成重量 j j j

  1. 如果 j = w [ i ] j=w[i] j=w[i] ,那么 d p [ i ] [ j ] = 1 dp[i][j]=1 dp[i][j]=1
  2. 否则
    • 如果我们看如果不用第 i i i 个砝码,能否凑出重量 j j j d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j]
    • 如果用了第 i i i 个砝码, 要么和第 i i i 个砝码作差凑出 j j j, 要么作和凑出重量 j j j ,: d p [ i − 1 ] [ a b s ( j − w [ i ] ) ] ∣ ∣ d p [ i − 1 ] [ j + w [ i ] ] dp[i-1][abs(j-w[i])] || dp[i-1][j+w[i]] dp[i1][abs(jw[i])]dp[i1][j+w[i]]

AC代码

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)
#define per(i,x,y) for(int i=x; i>=y; --i)
#define pushk push_back
#define popk pop_back
#define mem(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define ll long long
#define lp p<<1
#define rp p<<1|1
using namespace std;
const int N = 1e5+9;
int dp[108][N];
int a[N];
int main() {
	
	int n;
	cin>>n;
	int sum=0;
	rep(i,1,n){
		scanf("%d",a+i);
		sum+=a[i];
		//dp[i]
	}
//	dp[1][0]=1;
	rep(i,1,n){
		rep(j,0,sum){
			if(j==a[i]) dp[i][j]=1;
			else dp[i][j]=dp[i-1][j]||dp[i-1][abs(j-a[i])]||dp[i-1][j+a[i]];
		}
	} 
	int ans=0;
	rep(i,1,sum){
		if(dp[n][i]) ans++;
	}
	cout<<ans<<'\n';
	return 0;
}

说明

参考了:https://blog.dotcpp.com/a/84360

posted @ 2022-08-28 08:42  翔村亲亲鸟  阅读(113)  评论(0编辑  收藏  举报