假期日常笔记

完全背包

小蒜手里有 n 元钱全部用来买书,书的价格为 10 元,20 元,50 元,100 元。

问小蒜有多少种买书方案?(每种书可购买多本)

输入格式

一个整数 n,代表总共钱数。(1≤n≤1000)

输出格式

一个整数,代表选择方案种数。

Sample Input

20

Sample Output

2

Sample Input 2

15

Sample Output 2

0
#include <stdio.h>
int s[6]={10,20,50,100};
int dp[1005];
int main()
{
   int n,i,j,m;
   scanf("%d", &n);
   dp[0]=1;
   for(i=0; i<4; i++)
   	for(j=s[i]; j<=n; j++)
   		dp[j]+=dp[j-s[i]];
   printf("%d\n", dp[n]);
   return 0;
}

递归,dp

小蒜想知道把 M 个同样的苹果放在 N 个同样的盘子里,允许有的盘子空着不放,共有多少种不同的分法?(用 K 表示)5,1,1 和 1,5,1 是同一种分法。

输入格式

第一行是测试数据的数目 t(0≤t≤20)。

以下每行均包含两个整数 M 和 N,以空格分开。1≤M,N≤10。

输出格式

对输入的每组数据 M和N,用一行输出相应的 K。

Sample Input

1
7 3

Sample Output

8

 使用递归解决该问题。

        首先,当m<n时,无论如何都会有m-n个盘子是多余的。可以把盘子数量从n减少到m。

        其次,当m>=n时,分两种情况讨论:

                a) 改变n,使得同样多的苹果放到更少的盘子里,相当于把盘子空出来。设每次都空出来一个盘子,把盘子数量减一。这样传递能推导出空出2个、3个、····、n个的情况。

                b) 改变m,由于n不变,在每个盘子上都至少有一个苹果。每个盘子上都有苹果,相当于每个盘子上都没有苹果,所以将苹果个数减去n,变为m-n。

        终止条件有二:

                a) 当盘子个数为0时,无法放入苹果。此时分发为0种。

                b) 当苹果个数为0且盘子个数不为0时,被迫只有1种分法。
 

#include <stdio.h>
int apples(int, int);
int main()
{
	int m, n, t;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d %d", &m, &n);
		printf("%d\n", apples(m, n));
	}
	return 0;
}
int apples(int m, int n)
{
	if (m == 0 && n)  					//终止条件
		return 1;
	else if (n == 0)
		return 0; 
	else if (m < n) 					//苹果比盘子少 ,最多只能放m个盘子 
		return apples(m, m);
	else 								//有一个盘子不放苹果 + 每一个盘子都有苹果 
		return apples(m, n - 1) + apples(m - n, n); 
}

贪心

蒜头君最近买了一个书架用来存放奶牛养殖书籍,但书架很快被存满了,只剩最顶层有空余。

蒜头君共有 N 头奶牛 (1≤N≤20,000),每头奶牛有自己的高度(1≤Hi≤10,000),N 头奶牛的总高度为 S。书架高度为 B(1≤B≤S<2,000,000,007).

为了到达书架顶层,奶牛可以踩着其他奶牛的背,像叠罗汉一样,直到他们的总高度不低于书架高度。当然若奶牛越多则危险性越大。为了帮助John到达书架顶层,找出使用奶牛数目最少的解决方案吧。

输入格式

第 1 行:空格隔开的整数 NN 和 BB;

第 2 ~ N+1 行:第 i+1 行为整数 H_i。

输出格式

能达到书架高度所使用奶牛的最少数目。

Sample Input

6 40
6
18
11
13
19
11

Sample Output

3

 先冒泡排序,从大到小排序,大数相加得到结果加的次数最少

#include<stdio.h>
int main(){
	int n,b,a[20000],k=0,t,s=0;
	int i,j;
	scanf("%d %d",&n,&b);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	for(i=0;i<n;i++){                    //冒泡
		for(j=1;j<n-i;j++){
			if(a[j]>a[j-1]){
				t=a[j];
				a[j]=a[j-1];
				a[j-1]=t;
			}
		}
	}
	for(i=0;i<n;i++){                       //先k++;对于先判断再k++;应该就是贪心最基础的                        思想
		s+=a[i];
		k++;
		if(s>=b){
			break;
		}
	}
	printf("%d\n",k);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值