找数达人
时间限制:
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; }