现在的位置: 首页 > 综合 > 正文

fafu1411

2014年01月04日 ⁄ 综合 ⁄ 共 1203字 ⁄ 字号 评论关闭

这题说的是 一个整数 分解成几个素数的和  按这个数的含有的最大素数 进行排列给定的一个数 小于200 求这个数的 第k大的数是什么,然后让你计算出 第k大是组成数是什么.

分类进行dp 比如起始位进行dp  分类进行的dp可以按照从小到大的排列进行 大的数 只能用比他小的数 进行dp 类似于完全背包,这样在查找的时候也分类进行查找记得从大到小查找ok

#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
bool a[300];
int p[50],dp[50][300],ber[100];
void prime()
{
    int count=0;
    memset(a,0,sizeof(a));
    for(int i=2;i<=201;i++)
    {
        if(a[i]==0){p[count++]=i;}
        for(int j=0,k;j<count&&(k=p[j]*i)<=201;j++)
         {
          a[k]=1;
           if(i%p[j]==0) break;
       }
    }
    //for(int  i=0;i<count;i++)
   // printf("%d ",p[i]);
}
int work(int n,int k,int H)
{
    int count=0;
    for(int i=H;i>=0;i--) 
    {
        if(dp[i][n]<k)
        k-=dp[i][n];
        else if(dp[i][n]>=k)
        while(dp[i][n]>=k)
        {
            ber[count++]=p[i];
            n-=p[i];
            if(dp[i][n]<k)
            {
                k-=dp[i][n];
                break;
            }
            if(k==0||n==0) break;
        }
        if(k==0||n==0) break;

    }
    return count;
}
int main()
{
	//eopen("data.txt","r",stdin);
    prime();
    int n,k,H,sum;
   int i,j;
    while(scanf("%d%d",&n,&k)==2)
    {
        sum=0;
        memset(dp,0,sizeof(dp));
        if(!n&&!k) break;
        for(i=0;i<46;i++)
        {

           if(p[i]>n) {H=i;break;}
           dp[i][p[i]]=1;
           int st=p[i];
           for( j=i;j>=0;j--)
            {
                for(int g=st+p[j];g<=n;g++)
                if(dp[g-p[j]]!=0)
                {
                    dp[i][g]+=dp[i][g-p[j]];
                }
            }
            sum+=dp[i][n];
        }
        printf("%d\n",sum);
		if(k>sum)k=sum;
        int T=work(n,k,H);
        printf("%d=",n);
        for(i=0;i<T-1;i++)
        printf("%d+",ber[i]);
        printf("%d\n",ber[T-1]);
    }
     return 0;
}

                               

【上篇】
【下篇】

抱歉!评论已关闭.