程式設計師互動聯盟(第一屆程式設計大賽第一題)
阿新 • • 發佈:2019-01-03
題目大意:
將1到N的連續整陣列成的集合劃分成兩個子集合,且保證每個集合的數字和是相等的。
例如,輸入N=3,對應的集合{1,2,3} 可以被劃分為{3},{1,2}兩個子集合,這兩個子集合中元素分別的和是相等的。輸入7,輸出4
思路:
首先1,2,3……N所有元素的和為 S= N*(N+1)/2, 如果S不能被2整除,那麼一定不能劃分,否則各個集合裡面的元素之和為 S = N*(N+1)/4,下面運用動態規劃的思想,令count[i] 表示 和為 i 的方案數目,那麼 count[j] = count[j] + count[j-i] , 表示和為 j 的方案數,等於原先的值 加上 和為 j-i 的方案數。 也就是說,沒有加 i 之前的方案數 現在加上i之後,和變為 j, 那麼和為j的方案數也應該加上 和為j-i的方案數,有點繞。。。
很經典的動態規劃的例子,剛開始做竟然沒想起來。
#include <iostream> using namespace std; #define N 40 int main(){ int n,s; cin>>n; int count[400]; //該陣列count[i]表示和為i的方案數 memset(count,0,sizeof(count)); s = n*(n+1)/2; if(s%2!=0) cout<<0<<endl; s = s/2; count[0] = 1; for(int i=1;i<=n;i++){ for(int j=s;j>=i;j--){ count[j] += count[j-i]; } } cout<<count[s]/2<<endl; return 0; }