HDU 1085(dp 母函数)

题意: 拉登有面值 1 2 5  的钱币 分别 n1 n2 n5 个

          求出最大能连续组合到多大         

思路: 想来想去都有bug 最后简单粗暴的一个一个来处理了

 

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll __int64
#define MAXN 1000
#define INF 0x7ffffff
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int num[10000];
using namespace std;
int main()
{
    int n1,n2,n5;
    int i,j,flag,ans;
    while(scanf("%d%d%d",&n1,&n2,&n5)!=EOF)
    {
        if(n1==0&&n2==0&&n5==0) break;
        mem(num,-1);
        num[0]=0;
        flag=0;
        ans=0;
        int m=n1+n2*2+n5*5;  //最大8000
        int cnt=n1+n2+n5;   //最大3000
        while(cnt--)
        {
            if(n1)     {flag=1;n1--;}
            else if(n2){flag=2;n2--;}
            else if(n5){flag=5;n5--;}

            for(i=m;i>=0;i--)
            {
                if(num[i]==0)
                {
                  num[i+flag]=0;
                }
            }
        }
        for(i=0;i<=100000;i++)
        {
            //cout<<i<<"  "<<num[i]<<endl;
            if(num[i]==-1)
            {
                ans=i;break;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

 

母函数

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int num[10];
int c1[9000];
int c2[9000];
void fun()
{
    int n=num[0]+num[1]*2+num[2]*5;
    int i,j,k;
    memset(c2,0,sizeof(c2));
    memset(c1,0,sizeof(c1));
    for(i=0;i<=num[0];i++)
    {
        c1[i]=1;
    }

    for(j=0;j<=num[0];j++)
    {
        for(k=0;k<=num[1]*2;k+=2)
        {
            c2[j+k]+=c1[j];
        }
    }
    for(j=0;j<=n;j++)
    {
        c1[j]=c2[j];
        c2[j]=0;
    }

    /*for(i=0;i<=18;i++)
    {
        printf("%d %d\n",i,c1[i]);
    }*/

    for(j=0;j<=num[1]*2+num[0];j++)
    {
        for(k=0;k<=num[2]*5;k+=5)
        {
            c2[j+k]+=c1[j];
        }
    }
    for(j=0;j<=n;j++)
    {
        c1[j]=c2[j];
        c2[j]=0;
    }
}
int main()
{
  int n;
  int i,j,k;
  while(scanf("%d%d%d",&num[0],&num[1],&num[2])!=EOF)
  {
      if(num[0]==0&&num[1]==0&&num[2]==0) break;
      fun();
      for(i=0;i<=8010;i++)
      {
          if(c1[i]==0)
          {
              printf("%d\n",i);
              break;
          }
          //printf("%d %d\n",i,c1[i]);
      }
  }
  return 0;
}

 

posted @ 2014-08-16 00:41  sola94  阅读(119)  评论(0编辑  收藏  举报