65,211
社区成员
发帖
与我相关
我的任务
分享#include<stdio.h>
int main(void){
int M,N;
int temp,sum = 0,kindn;// 邮票面值的总和sum ,种类数kindnumber
int i,j,k;
int stamp[2][21]={0};//一行为邮票种类,二行为其数量
int value[101][21]={0};
//记录从1-M所需邮票的最少值和邮票数目
scanf("%d%d",&M,&N);
for(i=1,j=0;i<=N;i++){
scanf("%d",&temp);
sum += temp; //记录邮票总值
if(stamp[0][j] != temp){
++j;
stamp[0][j] = temp;
//记录各种邮票面值 后发现第一维无用,懒得改了
}
stamp[1][j] ++; // 记录temp面值邮票的数量
value[temp][0] = 1; //第0列记录所需邮票最少值
value[temp][j] = 1; //第temp列记录达到最少值需要的temp值邮票的数量
}
kindn = j; //邮票种类总数
if(sum < M){
printf("0\n");
return 1;
}
if(sum == M){
printf("%d\n",N);
return 1;
}
if(value[M][0] == 1){
printf("1\n");
return 1;
}
for(i=1;i<=M;i++){ //主循环,从1递增到M构成需要邮票的最少数
if(value[i][0] == 1) continue;
for(j=1;j<=i/2;j++){ //j 与 i-j 两两相加,取需邮票最少的一对更新数组
if(value[j][0] == 0 || value[i-j][0] == 0){
//有一个面值无法组合出来,则 value[i]无法组合出来
continue;
}
if(value[i][0] == 0
|| value[j][0]+value[i-j][0]<value[i][0]){
//初始化和寻找最小值
for(k=1;k<=kindn;k++){
if(value[j][k]+value[i-j][k] > stamp[1][k]){
break;
}
}
if(k > kindn){ //更新最小值
value[i][0] = value[j][0]+value[i-j][0];
for(k=1;k<=kindn;k++){
value[i][k] = value[j][k]+value[i-j][k];
}
}
}
}
}
printf("%d\n",value[M][0]);
//while(1) getchar();
return 1;
}
#include <stdio.h>
#define MAXN 20
#define MAXM 100
#define LARGE 1000
int main()
{
int total, n, i, j;
int face[MAXN];
int least[MAXM]; //least[k]表示凑成k元钱的最少硬币个数, 显然least[k] = min{least[k - face[i]] + 1}, 对i枚举.
scanf("%d%d", &total, &n);
for (i = 0; i < MAXM; ++i)
least[i] = LARGE; //初始化为无解
for (i = 0; i < n; ++i)
{
scanf("%d", &face[i]);
least[face[i]] = 1; //一张就可以
}
for (i = 0; i <= total; ++i)
{
int min = least[i];
for (j = 0; j < n; ++j)
{
if (i - face[j] >= 0 && least[i - face[j]] + 1 < min)
min = least[i - face[j]] + 1;
}
least[i] = min;
}
printf("%d\n", least[total]);
return 0;
}