poj 1837 Balance

此题第一印象想到的是穷举,但是肯定会超时。根据题意假设有一平衡因子j,当平衡因子达到0时,天平才会平衡。j>0时天平会向右偏,j<0会向左偏。
由于距离c[i]的范围是-15~15,砝码的重量范围是1~25,砝码的最大数量是20。程序中出现dp[1~20][-15~15]。假设所有的砝码都挂在天平的最左或最右端,平衡因子也就是力矩就会是15*25*20=7500,只要当天平的左端或右端的力矩达到最大力矩的一半3750就不可能再会平衡。dp[C][3750]刚好达到平衡。
dp[i][j]代表当天平上挂i个砝码重量因子达到j时的种类数目。现在就把这个问题分解成小问题,假设已知dp[i-1][j1],则要计算dp[i][j2]时就把dp[i-1][j1]加上,当然dp[i-1][j1]为0时就没必要加了。j1和j2之间相差的就是c*g,c一共有C种,g一共有G种。大致思路就这样了。

#include <stdio.h>
#include <string.h>
#define MAX_num 21
#define MAX 7500
#define balance 3750

int C, G;
int c[MAX_num], g[MAX_num], dp[MAX_num][MAX];

int main()
{
	while(scanf("%d%d", &C, &G) != EOF)
	{
		memset(dp, 0, sizeof(dp));
		dp[0][balance] = 1;
		for(int i = 0; i < C; i++) scanf("%d", &c[i]);
		for(int i = 0; i < G; i++) scanf("%d", &g[i]);
		for(int i = 1; i <= G; i++)
		{
			for(int j = 0; j <= MAX; j++)
			{
				if(dp[i - 1][j])
				{
					for(int k = 0; k < C; k++)
					{
						dp[i][j + c[k] * g[i - 1]] += dp[i - 1][j];
					}
				}
			}
		}
		printf("%d\n", dp[G][balance]);
	}
	return 0;
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值