codevs 1047 邮票面值设计

/*
开始没啥好的思路 暴力吧 T的太严重
加了k>n的特判  结果没数据…..然后又暴力生成了几组答案 打表
然而有没有数据 华丽的爆零了
正解 回溯+DP
回溯生成k数组 然后DP找最优解更新 

*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,k,f[550],a[55],ans[55],Ans;
void Judge()//DP判断  f[i]表示面值为i最少需要的票数 
{
    memset(f,127/3,sizeof(f));
    f[0]=0;
    int i=0;
    while(f[i]<=n)//连不起来 就停下 
      {
          i++;//累加保证可以组合成没个数 
          for(int j=1;j<=k;j++)
            if(i>=a[j])
              f[i]=min(f[i],f[i-a[j]]+1);//更新最优解 
      }
    i--;
    if(i>Ans)
      {
          Ans=i;
          for(int j=1;j<=k;j++)
            ans[j]=a[j];
      }
}
void Dfs(int l)
{
    if(l==k)
      {
          Judge();
          return;
      }
    for(int i=a[l]+1;i<=a[l]*n+1;i++)
      {
          a[++l]=i;
          Dfs(l);l--;
      }
}
int main()
{
    scanf("%d%d",&n,&k);
    Dfs(0);
    for(int i=1;i<=k;i++)
      printf("%d ",ans[i]);
    printf("\nMAX=%d\n",Ans);
    return 0;
}

 

posted @ 2016-06-07 20:05  一入OI深似海  阅读(238)  评论(1编辑  收藏  举报