TOJ 4367 ZOJ 3631 Watashi's BG / 背包 深搜

9 篇文章 0 订阅

Watashi's BG

时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte

描述

Watashi is the couch of ZJU-ICPC Team and he is very kind hearted. In ZJU-ICPC summer training camp, students are divided into several groups and each day one of the groups will design some problems to hold a contest. Today students of Group C are required to design the problems, and they spent the whole night to check to test data which made them very tired. Watashi decides to give some money as a reward to group C so that they can buy the lunch for free.

There are N days in the training schedule, and all students have booked their lunch for N days so we know how much money they will spend in each day. Now the leader of group C needs to decide how to use Watashi's money. Since the money is limited, it may not be possible that they can have free lunch every day. So each day the leader can choose to pay for the whole group's lunch by themselves or use Watashi's money. Of course, the leader wants to spend Watashi's money as much as possible, but he is too busy to write a program to calculate the maximum money he can spend from Watashi's reward. Can you help him?

输入

The input contains multiple test cases ( no more than 50 test cases ).
In each test case, first there are two integer, N ( 1 <= N <=30 ) , which is the number of training days,M ( 0 <= M <=10000000 ) , which is the reward money from Watashi.
Then there is a line containing N positive integers with the ith integer indicating the money group C need to pay for the lunch of the ith day. All these integers are no more than 10000000 and integers are seperated by a space.

输出

For each test case, output one line with an integer which is the maximum money group C can spend from Watashi's reward

样例输入

3 10
8 4 5

样例输出

9

背包优化一下可以过 dfs 就更松了

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[10000010];
int a[33];
int main()
{
	int n,i,j,sum = 0,m,k;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		sum = 0;
		for(i = 0;i < n; i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		if(sum <= m)
		{
			printf("%d\n",sum);
			continue;
		}
		memset(dp,0,sizeof(dp));
		sort(a,a+n);
		dp[0] = 1;
		sum = 0;
		for(i = 0;i < n; i++)
		{
			if(sum + a[i] > m)
				sum = m - a[i];
			for(j = sum; j >= 0; j--)
			{
				k = j + a[i];
					dp[k] = dp[j] | dp[k];
			}
			sum += a[i];
		}
		for(i = m; i >= 0; i--)
		{
			if(dp[i])
				break;
		}
		printf("%d\n",i);
	}
	return 0;
}


 

#include<stdio.h>
int a[31],count,n,m,flag = 1;
void dfs(int i,int sum)
{
	if(flag)
		return;
	if(count < sum)
		count = sum;
	if(sum == m)
	{
		flag = 1;
		return;
	}
	if(i >= n + 1)
		return;
	if(sum + a[i] <= m)
		dfs(i + 1,sum + a[i]);
	dfs(i + 1,sum);
}
int main()
{
	int i,sum;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		flag = 0;
		sum = 0;
		count=0;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		if(sum <= m)
		{
			printf("%d\n",sum);
			continue;
		}
		dfs(1,0);
		printf("%d\n",count);
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值