标签:des style blog color io os java ar strong
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 24002 Accepted Submission(s): 8458
Mean:
有n种物品,第一种物品的单价为v1,数量为m1;第二种物品的单价为v2,数量为m2.....现在要你将这些物品分为两堆,使得这两堆物品的价值尽量接近,输出两堆物品的价值。
analyse:
这道题的解法很多:dp,母函数.....,详见《编程之美》。
这里我用了两种方法来做了一下,发现后面的方法比母函数快多了。
Time complexity:O(n^2)
Source code:
母函数代码:
// Memory Time // 1347K 0MS // by : Snarl_jsb // 2014-09-18-18.50 #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<climits> #include<cmath> #define N 234567 #define LL long long using namespace std; int val[600],cnt[110]; int c1[N],c2[N]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); // freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin); // freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout); int n; while(cin>>n&&n>0) { long long sum=0; for(int i=1;i<=n;++i) { cin>>val[i]>>cnt[i]; sum+=val[i]*cnt[i]; } memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); for(int i=0;i<=cnt[1]*val[1];i+=val[1]) c1[i]=1; for(int i=2;i<=n;++i) { for(int j=0;j<=sum;++j) { for(int k=0;k<=cnt[i];++k) { c2[val[i]*k+j]+=c1[j]; } } for(int j=0;j<=sum;++j) { c1[j]=c2[j]; c2[j]=0; } } if(c1[sum/2]==2) { cout<<sum/2<<" "<<sum/2<<endl; continue; } int t=sum/2; int QAQ,TAT; int minn=987654321; for(int i=0;i<=sum;++i) { if(c1[i]) { if(abs(sum/2-i)<minn) { minn=abs(sum/2-i); QAQ=i; } } } TAT=sum-QAQ; if(QAQ<TAT) { QAQ^=TAT^=QAQ^=TAT; } cout<<QAQ<<" "<<TAT<<endl; } return 0; }
数学方法:
// Memory Time // 1347K 0MS // by : Snarl_jsb // 2014-09-18-23.05 #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<climits> #include<cmath> #define N 1000010 #define LL long long using namespace std; int val[N],cnt[N]; int buff[N]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); // freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin); // freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout); int n; while(cin>>n&&n>0) { long long v,t,idx=0,sum=0; for(int i=1;i<=n;i++) { cin>>v>>t; val[i]=v,cnt[i]=t; sum+=val[i]*cnt[i]; while(t--) { buff[++idx]=v; } } sort(buff+1,buff+1+idx); int half=sum/2; long long ans=0; for(int i=idx;i>=1;--i) { if(ans+buff[i]<=half) { ans+=buff[i]; } } cout<<sum-ans<<" "<<ans<<endl; } return 0; }
组合数学 - 母函数的变形 --- hdu 1171:Big Event in HDU
标签:des style blog color io os java ar strong
原文地址:http://www.cnblogs.com/acmer-jsb/p/3980377.html