蓝桥杯 砝码称重【第十二届】【省赛】【B组】

 

动态规划思想解题

将砝码按照输入的顺序,依次加入称量的过程中。

dp[0][]表示的是在加入第一个砝码后,当前可以表示称重的重量:
如题干中,砝码加入的顺序是1 4 6,故在第一个砝码(即重量为1的砝码)加入后,可称量的重量大小是1,故将dp[0][1]赋值为1。

dp[1][]表示的是在加入第二个砝码后,当前可以表示称重的重量:
如题干中加入第二个砝码质量为4时,可以称的重量为1+4=5和|1-4|=3。
只需根据上一行的数据进行测量即可,无需多考虑其他砝码的影响。

加入6后同理。

 

该题运用的动态规划是按照砝码加入的顺序来计算的,并不是计算每次有多少个砝码时可以称的重量。

如dp[0]* 表示的是第一个砝码进来的时候可以称的重量,而不是有一个砝码时可以称的重量,第一个进来的砝码质量就是输入的第一个质量。

不需要考虑每次多个砝码需要选取哪几个,所以才能简单的进行下一步的规划。

dp[1]* 就表示了加入第二个砝码后可称的重量,因为dp[0]已经计算了第一个砝码时可以称的重量,故dp[1]只需考虑加上或者减去这个n[1]砝码可以称的重量即可。
    ****
dp[i]表示了加入第i+1个砝码后可以称的重量,同理,由于dp[i-1]已经称量出了前i个砝码时可以称的重量,故执行时只需考虑最新加入的砝码即可 

#include<bits/stdc++.h>
using namespace std;

int dp[105][100005]={0};   //dp数组
int N;                     //砝码个数
int n[105];                //每个砝码的质量
int sum=0;                 //可以称的总重
int cnt=0;                 //答案


int main()
{
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>n[i];
		sum+=n[i];
	}
	
	dp[0][n[0]]=1;  //第1个砝码进来后可以称的重
	
	for(int i=1;i<N;i++)
	{
		for(int j=1;j<=sum;j++)
		{
			dp[i][j]=dp[i-1][j];  //复制上一个状态 
		}
		
		dp[i][n[i]]=1; //加进来第i+1个砝码,此时共i+1个砝码 
		
		for(int j=0;j<=sum;j++)
		{
			if(dp[i-1][j])
			{
				dp[i][j+n[i]]=1;  //通过之前的数据加上进来的新砝码的重量
				dp[i][abs(j-n[i])]=1;   //通过之前的数据减去进来的新砝码的重量

			}
		}
	}
	
	for(int j=0;j<=sum;j++)        //累加求出最后一行1的个数就是可以称重的个数
	{
		cnt+=dp[N-1][j];     
	}
	cout<<cnt;
	
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值