蓝桥杯—砝码称重(C语言解法)


题目描述


思路

  1. 借鉴了y总的思路点这里看思路
  2. 状态表示:f[i][j]的意义是i个砝码能称出重量为j的方案的集合,属性:f[i][j]为1或0,为1说明前i个砝码可以称出重量j
  3. 状态计算:可以将第i个物品分为三种状态,(放在左边,不放,放在右边)其中任何一种状态存在则f[i][j]存在
  4. 注意j的取值范围(-sum(全部放在左边)到sum(全部放在右边)),又因为j还是数组下标,所以j不能为负,所以在使用下标为j时要加sum使下标为正
  5. 结果表示f[n][j](j取值范围为1-sum)j取值范围为1-sum原因:0能称出来,但是不应该算一种,所以j从1开始,又因为称出来的正负重量是对称的(放在左边1,放在右边4、6,能称出来9,同理放在右边1,放在左边4、6,也能称出来9,但是计数的时候记了两次)所以遍历正数这边即可

代码

#include<stdio.h>
int f[110][100100];
int w[110];//存储各砝码的重量
int main(){
	int n,i,j;
	int count=0,sum=0;//存储个数与砝码和
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&w[i]);
		sum+=w[i];
	}//读入数据并求出砝码和
	f[0][sum]=1;//!!!!f[0][0]为1,因为下标都加上了sum,所以f[0][sum]=1!!!很重要
	for(i=1;i<=n;i++){
		for(j=-sum;j<=sum;j++){//注意j的取值范围
			f[i][j+sum]=f[i-1][j+sum];//不放砝码i
			if(j+sum-w[i]>=0)f[i][j+sum] =f[i-1][j+sum-w[i]] || f[i][j+sum];//i放在右侧
			if(j+sum+w[i]<=2*sum)f[i][j+sum]= f[i-1][j+sum+w[i]] || f[i][j+sum];//i放在左侧
		}
	}
	for(j=1;j<=sum;j++){//注意循环起点与终点
		if(f[n][j])count++;
	}
	printf("%d",count);
	return 0;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM