完全背包
小蒜手里有 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);
}