藍橋杯—砝碼稱重(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