【20171005】Luogu P1164 小A点菜

题目背景 Background
uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种。 uim指着墙上的价目表(太低级了没有菜单),说:“随便点”。
 
 题目描述 Description
不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩M元(M<=10000)。
餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i种卖ai元(ai<=1000)。由于是很低端的餐馆,所以每种菜只有一份。
小A奉行“不把钱吃光不罢休”,所以他点单一定刚好吧uim身上所有钱花完。他想知道有多少种点菜方法。
由于小A肚子太饿,所以最多只能等待1秒。
 
 输入输出格式 Input/output
输入格式:
第一行是两个数字,表示N和M。
第二行起N个正数ai(可以有相同的数字,每个数字均在1000以内)。
输出格式:
一个正整数,表示点菜方案数。
 
 输入输出样例 Sample input/output
样例测试点#1

输入样例:

4 4
1 1 2 2


输出样例:

3

鄙人不才,用的是回溯:

 1 #include <stdio.h>
 2 #include<stdlib.h>
 3 int way=0; //方案数 
 4 int price[101];//菜品价格(一看就是黑店) 
 5 int light[101]={0};//标记菜品是不是上过了(都说了Low,就一盘菜) 
 6 int Sum=0;//已经点了的菜品总价 
 7 int n,m;//看题吧~~~ 
 8 int cmp(const void *a,const void *b)//由大到小排序 
 9 {
10     return *(int *)b-*(int *)a;
11 }
12 void Search(int length,int floor,int start)
13 {
14     if(floor>length||Sum>m)
15     {
16         //好像忘了写什么……
17         //哦,这个时候点的菜太多了(没菜点了) 
18         //或者uim被吃穷了…… 
19         return ;
20     }
21     else if(Sum==m)//满足了小A邪恶的愿望 
22     {
23         way++;
24         return ;
25     }
26     else
27     {
28         int i;
29         for(i=start;i<length;i++)
30         {
31             if(light[i]==1)continue;//每道菜上一次 
32             Sum+=price[i];//加钱,加钱 
33             light[i]=1;//告诉你上过这道菜了啊,我不做这菜了啊 
34             Search(length,floor+1,i+1);//怂什么,深搜 
35             light[i]=0;
36             Sum-=price[i];
37         }
38         return ;
39     }
40 }
41 int main()
42 {
43     int i;
44     int len;
45     scanf("%d%d",&n,&m);
46     len=n;
47     for(i=0;i<len;i++)
48     {
49         scanf("%d",&price[i]);
50         if(price[i]>m)//uim一道菜都付不起,那还点来干嘛 
51         {
52             i--;len--;
53         }
54     }
55     qsort(price,len,sizeof(price[0]),cmp);
56     
57     Search(len,0,0);
58     /*
59     for(i=0;i<len;i++)
60     {
61       printf("%d ",price[i]);
62     }
63     printf("
");*/
64     printf("%d
",way);
65     return 0;
66 }

已经ac

原文地址:https://www.cnblogs.com/CXSheng/p/5171214.html