hdu 2152 Fruit ( 母函数 )

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2152

母函数详细讲解:http://blog.csdn.net/xiaofei_it/article/details/17042651

 

hdu  相关练习题目: 1171  1028  1085 2082 1398  1709  1059

hdu  2152

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<stdlib.h>
 5 
 6 using namespace std;
 7 
 8 int main ( )
 9 {
10     int n,m,Min[105],Max[105],a[105],b[105];
11     while(~scanf("%d%d",&n,&m))
12     {
13         memset(a,0,sizeof(a));
14         a[0]=1;
15         for(int i=1;i<=n;i++)
16             scanf("%d%d",&Min[i],&Max[i]);
17         for(int i=1;i<=n;i++)
18         {
19             memset(b,0,sizeof(b));
20             for(int j=Min[i];j<=Max[i];j++)
21                 for(int k=0;k+j<=m;k++)
22                     b[k+j]+=a[k];
23             memcpy(a,b,sizeof(b));
24         }
25         printf("%d\n",a[m]);
26     }
27     return 0;
28 }
View Code

 hdu  1709  差值的实现

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 
 9 const int T=1e4+5;
10 
11 int a[20],n,dp[T],mid[T];
12 
13 //void print( int dp[], int n )
14 //{
15 //    for(int i=0;i<=n;i++)
16 //        cout << dp[i] <<" ";
17 //    cout <<endl;
18 //}
19 
20 
21 int main( )
22 {
23     int n,sum,a[105],dp[T],mid[T];
24     while(~scanf("%d",&n))
25     {
26         sum=0;
27         for(int i=1;i<=n;i++){
28             scanf("%d",&a[i]);
29             sum+=a[i];
30         }
31         memset(dp,0,sizeof(dp));
32         dp[0]=1;
33         for(int i=1;i<=n;i++)
34         {
35             memset(mid,0,sizeof(mid));
36             for(int j=0;j<=1;j++)
37             for(int k=0;k+j*a[i]<=sum;k++)
38             {
39                 mid[k+j*a[i]] |= dp[k];
40                 mid[ abs(k-j*a[i]) ] |= dp[k];  //找差值是否存在
41             }
42             memcpy(dp,mid,sizeof(mid));
43         }
44         int cnt=0;
45         for(int i=1;i<=sum;i++)
46             if(!dp[i])
47                 cnt++;
48         printf("%d\n",cnt);
49         for(int i=1;i<=sum;i++)
50             if(!dp[i])
51             {
52                 printf("%d",i);
53                 dp[i]=1;
54                 break;
55             }
56         for(int i=1;i<=sum;i++)
57             if( !dp[i] )
58                 printf(" %d",i);
59         if(cnt)
60         printf("\n");
61     }
62     return 0;
63 }
View Code

hdu  2069   需要控制硬币总个数

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 const int T=255;
 9 
10 void print( int dp[], int n )
11 {
12     for(int i=0;i<=n;i++)
13         cout << dp[i] <<" ";
14     cout <<endl;
15 }
16 
17 int main( )
18 {
19     int n,a[5]={1,5,10,25,50},dp[T][T],mid[T][T];
20     memset(dp,0,sizeof(dp));
21     memset(mid,0,sizeof(mid));
22     dp[0][0]=1;
23     for(int i=0;i<5;i++)
24     {
25         for(int j=0;j*a[i]<T;j++)  // 硬币个数
26             for(int k=0;k+j*a[i]<T;k++)
27                 for(int l=0;j+l<=100;l++)  // 控制硬币总个数
28                 mid[k+j*a[i]][j+l]+=dp[k][l];
29 
30         memcpy(dp,mid,sizeof(mid));
31         memset(mid,0,sizeof(mid));
32     }
33 
34 //    for(int i=1;i<=26;i++)
35 //        cout <<dp[26][i] <<" ";
36 //        cout <<endl;
37 
38     while(~scanf("%d",&n))
39     {
40         int sum=0;
41         for(int i=0;i<=100;i++)
42             sum+=dp[n][i];
43         printf("%d\n",sum);
44     }
45     return 0;
46 }
View Code

 hdu  1059  两种方法 背包 || 母函数(???为什么一定要取模)

背包

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int sum,i,X=0;
 6 int a[7],Max[210005];
 7 void completepack( )
 8 {
 9     for(int j=i;j<=sum;j++)
10        Max[j]=max(Max[j],Max[j-i]+i);
11 }
12 void zeroOnepack( )
13 {
14     for(int k=1;;k*=2)
15     {
16         if(k>a[i]) break;
17         for(int j=sum;j>=k*i;j--)
18            Max[j]=max(Max[j],Max[j-k*i]+k*i);
19         a[i]-=k;
20     }
21     if(a[i]==0)   return ;
22     for(int j=sum;j>=a[i]*i;j--)
23         Max[j]=max(Max[j],Max[j-i*a[i]]+a[i]*i);
24 }
25 int main()
26 {
27     while(scanf("%d%d %d%d %d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6]))
28     {
29         memset(Max,0,sizeof(Max));
30        if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0) break;
31        X++;
32        printf("Collection #%d:\n",X);
33        sum=1*a[1]+2*a[2]+3*a[3]+4*a[4]+5*a[5]+6*a[6];
34        if(sum%2!=0)  printf("Can't be divided.\n");
35        else
36        {
37             sum/=2;
38             for(i=1;i<=6;i++)
39             {
40                 if(i*a[i]>=sum) completepack();
41                 else zeroOnepack();
42             }
43             if(Max[sum]==sum)  printf("Can be divided.\n");
44             else    printf("Can't be divided.\n");
45        }
46        printf("\n");
47     }
48 }
View Code

母函数

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 const int T=20005;
 8 
 9 void print( int dp[],int sum )
10 {
11     for(int i=0;i<=sum;i++)
12         printf("%d ",dp[i]);
13     printf("\n");
14 }
15 
16 
17 int main()
18 {
19     int dp[T],mid[T],num[10],c=1,sum,flag;
20     while(1)
21     {
22         sum=0;  flag=0;
23         for(int i=1;i<=6;i++){
24             scanf("%d",&num[i]);
25         }
26         if( !( num[1]||num[2]||num[3]||num[4]||num[5]||num[6] ) ) break;
27         for(int i=1;i<=6;i++)
28         {
29             num[i]%=30;    //为什么用母函数一点要取模呢,要不然就RE
30             sum+=num[i]*i;
31         }
32         printf("Collection #%d:\n",c++);
33         if( sum%2 ) flag=1;
34         else
35         {
36             memset(dp,0,sizeof(dp));
37             dp[0]=1;
38             sum/=2;
39             for(int i=1;i<=6;i++)
40             {
41                 memset(mid,0,sizeof(mid));
42                 for(int j=0;j<=num[i];j++)
43                 for(int k=0;k+j*i<=sum;k++){
44                     mid[k+i*j] |= dp[k];
45                   //  printf("%d %d %d\n",i,j,k);
46                 }
47                 memcpy(dp,mid,sizeof(mid));
48 
49 //                print( dp , sum);
50             }
51             if( !dp[sum] )  flag=1;
52         }
53         if( flag ) printf("Can't be divided.\n\n");
54         else    printf("Can be divided.\n\n");
55     }
56     return 0;
57 }
View Code

 

posted @ 2014-04-02 20:08  lysr__tlp  阅读(227)  评论(0编辑  收藏  举报