NIT-OJ-1449-最少硬币问题-解题报告
来源:互联网 发布:linux下oracle启动 编辑:程序博客网 时间:2024/06/09 08:03
问题描述:
设有n种不同面值的硬币,各硬币的面值存于数组T[1:n]中。现要用这些面值的硬币来
找钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。
对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。
算法设计:
对于给定的1≤n≤10,硬币面值数组T和可以使用的各种面值的硬币个数数组Coins,以
及钱数m,0≤m≤20001,计算找钱m的最少硬币数。
数据输入:
输入的第一行中只有1 个整数给出n的值,第2 行起每
行2 个数,分别是T[j]和Coins[j]。最后1 行是要找的钱数m。
结果输出:
将计算出的最少硬币数输出,问题无解时输出-1。
Sample input
3
1 3
2 3
5 3
18
Sample output
5
根据这个题意,就是从这么多个硬币中选最少符合条件的硬币个数。对这种题目我没什么想法,因为DP学的也不是很好,在这里写一下我的实现,仅给各位做一个参考。
我的理解:
1.先看题目输入数据的限制条件,只有n和m有限制,那我就做一个20002的数组存 DP过程中 的值。
2.硬币个数是有限的,那我就把这些硬币看成一个个的而不是一堆堆的。
我的实现过程:
结构体数组存硬币面额和对应的数量
struct Coine
{
int Coin;
int Count;
}g_nInputList[MAX];
DP中间过程的表 int g_nDPList[MAX]
输入的硬币面值种类int g_nInputCoinN
输入的要找的钱的值int g_nNeedCoin
输入函数即可如下表示
void ProcInput()
{
int i = g_nInputCoinN;
while (i--)
{
scanf("%d %d", &g_nInputList.Coin, &g_nInputList.Count);
}
scanf("%d", &g_nNeedCoin);
}
DP的实现:
总共的硬币个数,每个硬币一个循环,第一个硬币的时候初始化 g_nDPList[0] = 1;作为起始条件。
第一个硬币的时候从数组的尾部开始向前递增,遇到大于 0 的g_nDPList 时候把这个第i个数加上这个硬币的值 存为 TempSUM 再判断g_nDPList[TempSUM] 是否越界,超过g_nNeedCoin 的直接舍弃,否则 再判断g_nDPList[TempSUM] 是否为 0,若为0则直接赋值为g_nDPList[TempSUM] = 1,否则判断g_nDPList[TempSUM] 值是否大于g_nDPList + 1 ,若是则表示能用 g_nDPList + 1 个硬币表示 i 这个值,所以赋值为:g_nDPList[TempSUM] = g_nDPList + 1。否则就舍弃。这样把每个硬币一个这样的循环做完就可以知道能否表示 g_nNeedCoin 这个值了。
实现过程:
void GetResoult()
{
int i = g_nInputCoinN;
memset(g_nDPList, 0, sizeof(g_nDPList));
g_nDPList[0]=1;
while (i--)
{
while (g_nInputList.Count--)
{
int j = g_nNeedCoin + 1;
while(j--)
{
if(g_nDPList[j] > 0 && (g_nInputList.Coin + j) <= g_nNeedCoin)
{
if (0 == g_nDPList[g_nInputList.Coin + j] ||
g_nDPList[g_nInputList.Coin + j] > (g_nDPList[j] + 1))
{
g_nDPList[g_nInputList.Coin + j] = (g_nDPList[j] + 1);
}
}
}
}
}
}
注意,因为是 g_nDPList[0] = 1 这样的初始条件,所以每个值所能表示的最少硬币数其实应该是 g_nDPList - 1 个,所以这样就方便了我们输出的编写。如果不能表示,则 g_nDPList[g_nNeedCoin] 应该是 0,如果可以表示,则至少是1 以上。所以输出就可以这样写了:
void ProcOutput()
{
printf("%d/n",g_nDPList[g_nNeedCoin] - 1);
}
Run IDSubmit timeJudge StatusProblem IDLanguageRun timeMemory
797762009-02-02 18:38:06Accepted 1449 C 190MS304K
设有n种不同面值的硬币,各硬币的面值存于数组T[1:n]中。现要用这些面值的硬币来
找钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。
对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。
算法设计:
对于给定的1≤n≤10,硬币面值数组T和可以使用的各种面值的硬币个数数组Coins,以
及钱数m,0≤m≤20001,计算找钱m的最少硬币数。
数据输入:
输入的第一行中只有1 个整数给出n的值,第2 行起每
行2 个数,分别是T[j]和Coins[j]。最后1 行是要找的钱数m。
结果输出:
将计算出的最少硬币数输出,问题无解时输出-1。
Sample input
3
1 3
2 3
5 3
18
Sample output
5
根据这个题意,就是从这么多个硬币中选最少符合条件的硬币个数。对这种题目我没什么想法,因为DP学的也不是很好,在这里写一下我的实现,仅给各位做一个参考。
我的理解:
1.先看题目输入数据的限制条件,只有n和m有限制,那我就做一个20002的数组存 DP过程中 的值。
2.硬币个数是有限的,那我就把这些硬币看成一个个的而不是一堆堆的。
我的实现过程:
结构体数组存硬币面额和对应的数量
struct Coine
{
int Coin;
int Count;
}g_nInputList[MAX];
DP中间过程的表 int g_nDPList[MAX]
输入的硬币面值种类int g_nInputCoinN
输入的要找的钱的值int g_nNeedCoin
输入函数即可如下表示
void ProcInput()
{
int i = g_nInputCoinN;
while (i--)
{
scanf("%d %d", &g_nInputList.Coin, &g_nInputList.Count);
}
scanf("%d", &g_nNeedCoin);
}
DP的实现:
总共的硬币个数,每个硬币一个循环,第一个硬币的时候初始化 g_nDPList[0] = 1;作为起始条件。
第一个硬币的时候从数组的尾部开始向前递增,遇到大于 0 的g_nDPList 时候把这个第i个数加上这个硬币的值 存为 TempSUM 再判断g_nDPList[TempSUM] 是否越界,超过g_nNeedCoin 的直接舍弃,否则 再判断g_nDPList[TempSUM] 是否为 0,若为0则直接赋值为g_nDPList[TempSUM] = 1,否则判断g_nDPList[TempSUM] 值是否大于g_nDPList + 1 ,若是则表示能用 g_nDPList + 1 个硬币表示 i 这个值,所以赋值为:g_nDPList[TempSUM] = g_nDPList + 1。否则就舍弃。这样把每个硬币一个这样的循环做完就可以知道能否表示 g_nNeedCoin 这个值了。
实现过程:
void GetResoult()
{
int i = g_nInputCoinN;
memset(g_nDPList, 0, sizeof(g_nDPList));
g_nDPList[0]=1;
while (i--)
{
while (g_nInputList.Count--)
{
int j = g_nNeedCoin + 1;
while(j--)
{
if(g_nDPList[j] > 0 && (g_nInputList.Coin + j) <= g_nNeedCoin)
{
if (0 == g_nDPList[g_nInputList.Coin + j] ||
g_nDPList[g_nInputList.Coin + j] > (g_nDPList[j] + 1))
{
g_nDPList[g_nInputList.Coin + j] = (g_nDPList[j] + 1);
}
}
}
}
}
}
注意,因为是 g_nDPList[0] = 1 这样的初始条件,所以每个值所能表示的最少硬币数其实应该是 g_nDPList - 1 个,所以这样就方便了我们输出的编写。如果不能表示,则 g_nDPList[g_nNeedCoin] 应该是 0,如果可以表示,则至少是1 以上。所以输出就可以这样写了:
void ProcOutput()
{
printf("%d/n",g_nDPList[g_nNeedCoin] - 1);
}
Run IDSubmit timeJudge StatusProblem IDLanguageRun timeMemory
797762009-02-02 18:38:06Accepted 1449 C 190MS304K
- NIT-OJ-1449-最少硬币问题-解题报告
- NIT-OJ-1024-全文检索-解题报告
- NIT-OJ-1022-展开字符串-解题报告
- OJ解题报告 4976:硬币
- 【解题报告】硬币问题
- NIT-OJ-1411-恶魔杀怪-解题报告
- 南邮 OJ 1221 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 【dp】最少硬币问题
- 最少硬币问题
- 最少硬币找零问题
- 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- NIT-OJ-1022-展开字符串-解题报告
- The Relationship Between ZB,NB,SB and LP 第一篇
- NIT-OJ-1411-恶魔杀怪-解题报告
- 主要关于C的标准化输输出
- 6个跟踪网站流量的站点[译文109]
- NIT-OJ-1449-最少硬币问题-解题报告
- 无向连通图的生成树个数
- System.Management.ManagementException: 访问遭到拒绝的解决方案
- 开博
- Fedora 9 - 10 X64 安装
- 揭示PHP成功背后的秘密:PHP创始人访谈录
- SQL Server BI Step by Step SSIS 7 (End) --- 事务,错误输出,事件处理,日志记录
- 关于eclipse中继承类和实现接口
- 读书反思