NYOJ 1221 找数达人(01背包)

找数达人

时间限制: 1000 ms  |  内存限制: 65535 KB
难度:2
描述

 

简单的题意如下:

小明最近做出了一道题:如何在一组数中寻找三个数,这三个数的和等于一给出的定值m,洋洋得意。于是小华不乐意了,别问为什么...,于是小华说,你能找找在一组数字中是否有n个数,使得这n个数的和等于一给定的定值m吗?


 1): 0 < n <= 10000

 2): 0 < 序列长度 <= 10000

 3): 0 <= m <=10000

 4): 0 <= 数组中的数 <=10000

还有比这更简单易懂的题目吗???


输入
多组数据,每组两行,第一行为序列内容,第二行为m的值。
输出
如能找到,输出Yes,否则,输出No。
样例输入
1 3 4 5
5
1 3 4 5 9
2
样例输出
Yes
No
解题思路 :这个题吧,刚开始看还真没一点思路,就连开始的数据读入也不知所措。静下心好好想想,原来是读入字符串,把其中的整数提取出来,用gets()读取字符串,再利用双重循环提取数据(具体过程见代码)。然后...然后就是一个令我迷惑至今的问题,我首先想到的是贪心算法,利用和nyoj91类似的思路,贪心计算,自己测试的所有数据完全没错,但就是提交WrongAnswer,我也是醉了.......没办法寻找另一种方法吧,其实这个题可以转化成01背包,只不过比较特殊(物品的体积与价值相等),m作为背包的容积。代码如下:
具体代码:
#include <stdio.h>
#include <string.h>
#define max(a,b) a>b?a:b
char str[100000];
int c[100000];
int v[100000];
int dp[100000];
int main()
{
	while(gets(str))
	{
		int i,j=0,sum;
		int len=strlen(str);
		for(i=0;i<len;i++)
		{
			sum=0;
			while(str[i]>='0'&&str[i]<='9')
			{
				sum=sum+str[i]-'0';
				if(str[i+1]>='0'&&str[i+1]<='9'&&i+1<len)
					sum=sum*10;
				i++;
			}
			c[j]=sum;v[j]=sum;
			j++;
		}
		int m,k,T=0;
		scanf("%d",&m);
		memset(dp,0,sizeof(dp));
		for(i=0;i<j;i++)
		{
			for(k=m;k>=c[i];k--)
			{
				dp[k]=max(dp[k],dp[k-c[i]]+v[i]);
				if(dp[k]==m)
				{
					T=1;
					break;
				}
			}
			if(T==1)
				break;
		}
		if(T==1)
			printf("Yes\n");
		else
			printf("No\n");
		getchar();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值