iTom's blog

在下并没有当黑客的水平…

UVa 12955 Factorial

Problemuva.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;
}

阅读更多
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/HackerTom/article/details/51556872
文章标签: uva ACM
个人分类: acm
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

UVa 12955 Factorial

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭