fafu 1411

想了好久都没想到怎么去判断当分类dp的时候大于或者等于要求的 值时应该怎么半 后来经过停了 qlx的想法 然后就 敲了出来

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

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

  1. #include <iostream>   
  2. #include<cstdio>   
  3. #include<string.h>   
  4. using namespace std;  
  5. bool a[300];  
  6. int p[50],dp[50][300],ber[100];  
  7. void prime()  
  8. {  
  9.     int count=0;  
  10.     memset(a,0,sizeof(a));  
  11.     for(int i=2;i<=201;i++)  
  12.     {  
  13.         if(a[i]==0){p[count++]=i;}  
  14.         for(int j=0,k;j<count&&(k=p[j]*i)<=201;j++)  
  15.          {  
  16.           a[k]=1;  
  17.            if(i%p[j]==0) break;  
  18.        }  
  19.     }  
  20.     //for(int  i=0;i<count;i++)   
  21.    // printf("%d ",p[i]);   
  22. }  
  23. int work(int n,int k,int H)  
  24. {  
  25.     int count=0;  
  26.     for(int i=H;i>=0;i--)   
  27.     {  
  28.         if(dp[i][n]<k)  
  29.         k-=dp[i][n];  
  30.         else if(dp[i][n]>=k)  
  31.         while(dp[i][n]>=k)  
  32.         {  
  33.             ber[count++]=p[i];  
  34.             n-=p[i];  
  35.             if(dp[i][n]<k)  
  36.             {  
  37.                 k-=dp[i][n];  
  38.                 break;  
  39.             }  
  40.             if(k==0||n==0) break;  
  41.         }  
  42.         if(k==0||n==0) break;  
  43.   
  44.     }  
  45.     return count;  
  46. }  
  47. int main()  
  48. {  
  49.     //eopen("data.txt","r",stdin);   
  50.     prime();  
  51.     int n,k,H,sum;  
  52.    int i,j;  
  53.     while(scanf("%d%d",&n,&k)==2)  
  54.     {  
  55.         sum=0;  
  56.         memset(dp,0,sizeof(dp));  
  57.         if(!n&&!k) break;  
  58.         for(i=0;i<46;i++)  
  59.         {  
  60.   
  61.            if(p[i]>n) {H=i;break;}  
  62.            dp[i][p[i]]=1;  
  63.            int st=p[i];  
  64.            for( j=i;j>=0;j--)  
  65.             {  
  66.                 for(int g=st+p[j];g<=n;g++)  
  67.                 if(dp[g-p[j]]!=0)  
  68.                 {  
  69.                     dp[i][g]+=dp[i][g-p[j]];  
  70.                 }  
  71.             }  
  72.             sum+=dp[i][n];  
  73.         }  
  74.         printf("%d ",sum);  
  75.         if(k>sum)k=sum;  
  76.         int T=work(n,k,H);  
  77.         printf("%d=",n);  
  78.         for(i=0;i<T-1;i++)  
  79.         printf("%d+",ber[i]);  
  80.         printf("%d ",ber[T-1]);  
  81.     }  
  82.      return 0;  
  83. }  
原文地址:https://www.cnblogs.com/Opaser/p/3662055.html