Problem:uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4834
开始想多了,想着不能简单贪心,要用dp,于是写了下面的代码:
题目 n 最大1e5,而 15! > 1e5,所以 fac[] 开16就够
dp[0]表示钞票总额,dp[1]表示钞票数
#include <stdio.h>
#include <string.h>
int fac[16],dp[2][100001];
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int i,n;
for(i=n=fac[0]=1;i<16;i++)
fac[i]=n*=i;
while(~scanf("%d",&n))
{
int j;
memset(dp,0,sizeof(dp));
for(i=0;i<=n;i++)
for(j=fac[i];j<=n;j++)
{
if(dp[0][j-fac[i]]+fac[i]>dp[0][j])
{
dp[0][j]=dp[0][j-fac[i]]+fac[i];
dp[1][j]=dp[1][j-fac[i]]+1;
}
if(dp[0][j-fac[i]]+fac[i]==dp[0][j])
dp[1][j]=min(dp[1][j],dp[1][j-fac[i]]+1);
}
printf("%d\n",dp[1][n]);
}
return 0;
}
过了样例,交上去超时
后来想:1! =1 啊,所以肯定能用 1! 补充 n 减去其它阶乘剩下的数
题目相当于:某种货币有面值分别为 1! 、 2! 、…、15! 的钞票,要买价格为 n 的物品,最少要多少张钞票…
#include <stdio.h>
int fac[16];
int main()
{
int i,n;
for(i=n=fac[0]=1;i<16;i++)
fac[i]=n*=i;
while(~scanf("%d",&n))
{
int num=0;
for(i=15;n>0&&i>0;n%=fac[i--])
num+=n/fac[i];
printf("%d\n",num);
}
return 0;
}