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 }
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 }
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 }
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 }
母函数
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 }