hdu 1171 Big Event in HDU(dp 01背包 母函数)
题意:有n种物品 每种价值 vi 有 ci件
问分成两堆 最平均的价值分配是多少
思路:
01背包
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; int v[100],m[100]; int dp[300000]; int main() { int n; int i,j,k; while(scanf("%d",&n)!=EOF) { if(n<0) break; int sum=0; for(i=0;i<n;i++) { scanf("%d%d",&v[i],&m[i]); sum+=v[i]*m[i]; } memset(dp,0,sizeof(dp)); dp[0]=1; for(i=0;i<n;i++) { for(j=0;j<m[i];j++) { for(k=sum;k>=v[i];k--) { if(dp[k-v[i]]==1) dp[k]=1; } } } int half=sum/2; while(dp[half]==0) half--; printf("%d %d\n",sum-half,half); } return 0; }
母函数
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; int c1[300000],c2[300000]; int v[100],m[100]; int n; void fun(int sum) { int i,j,k; int tsum=0; memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); c1[0]=1; for(i=0;i<n;i++) { int add=v[i]; //tsum+=v[i]*m[i]; for(j=0;j<=sum;j++) { for(k=0;k<=m[i]*v[i];k+=add) { c2[j+k]+=c1[j]; } } for(j=0;j<=sum;j++) { c1[j]=c2[j]; c2[j]=0; } } } int main() { int i,j,k; while(scanf("%d",&n)!=EOF) { if(n<0) break; int sum=0; for(i=0;i<n;i++) { scanf("%d%d",&v[i],&m[i]); sum+=v[i]*m[i]; } fun(sum); int half=sum/2; while(c1[half]==0) half--; printf("%d %d\n",sum-half,half); } return 0; }