SGU 116 Index of super-prime

        定义了一种数super prime,数的本身是一个素数,且在素数表里的下标(从1开始)也是一个素数。然后给定一个n,求用最少的superprime相加得到n的方法。

        解法,因为数据很小,Number is not more than 10000.   在10000内的super prime也很少,只有201个,所以可以直接本地打表得出。随后就是一个很简单的背包。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int sprime[201]={3,5,11,17,31,41,59,67,83,109,127,157,179,191,211,241,277,283,331,353,367,401,431,461,509,547,563,587,599,617,709,739,773,797,859,877,919,967,991,1031,1063,1087,1153,1171,1201,1217,1297,1409,1433,1447,1471,1499,1523,1597,1621,1669,1723,1741,1787,1823,1847,1913,2027,2063,2081,2099,2221,2269,2341,2351,2381,2417,2477,2549,2609,2647,2683,2719,2749,2803,2897,2909,3001,3019,3067,3109,3169,3229,3259,3299,3319,3407,3469,3517,3559,3593,3637,3733,3761,3911,3943,4027,4091,4133,4153,4217,4273,4339,4397,4421,4463,4517,4549,4567,4663,4759,4787,4801,4877,4933,4943,5021,5059,5107,5189,5281,5381,5441,5503,5557,5623,5651,5701,5749,5801,5851,5869,6037,6113,6217,6229,6311,6323,6353,6361,6469,6599,6653,6661,6691,6823,6841,6863,6899,7057,7109,7193,7283,7351,7417,7481,7523,7607,7649,7699,7753,7841,7883,8011,8059,8101,8117,8221,8233,8287,8377,8389,8513,8527,8581,8719,8747,8761,8807,8849,8923,8999,9041,9103,9293,9319,9403,9461,9539,9619,9661,9739,9833,9859,9923,9973
};
int f[10001],cnt[10001],line[10001];
bool cmp(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int i,j,n,ans,ll;
    memset(f,-1,sizeof(f));
    memset(cnt,0,sizeof(cnt));
    for (i=3; i<10001; i++)
    {
        for (j=0; j<201; j++)
        {
            if (i == sprime[j])
            {
                f[i]=-sprime[j];
                cnt[i]=1;
                break;
            }
            else if (sprime[j] > i)
            {
                break;
            }
            else if (i > sprime[j])
            {
                if (f[i-sprime[j]] != -1 && (cnt[i] == 0 || cnt[i] > cnt[i-sprime[j]]+1))
                {
                    f[i]=sprime[j];
                    cnt[i]=cnt[i-sprime[j]]+1;
                }
            }
        }
    }
    scanf("%d",&n);
    if (f[n] == -1)
    {
        printf("0\n");
        return 0;
    }
    ll=0;
    printf("%d\n",cnt[n]);
    while (f[n] > 0)
    {
        line[ll]=f[n];
        ll++;
        n-=f[n];
    }
    line[ll]=-f[n];
    ll++;
    sort(line,line+ll,cmp);
    for (i=0; i<ll-1; i++)
    {
        printf("%d ",line[i]);
    }
    printf("%d\n",line[i]);
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值