這道題我首先的思路是dfs,確實可以做,但是n上了30之後就執行超時了。說明dfs還是蠻容易超時的,適合小資料。
#include#includeusing namespace std;
long long allsum=0;
int cnt=0;
int n;
void dfs(int i,long long sum)
if(sum>allsum/2)
return;
for(int j=i-1;j>=1;j--)
}int main()
dfs(n,n);
cout<
後來去網上看了看其他人的思路,發現媽耶,可以用dp做。
因為這道題其實也可以類似成「裝東西」的題,所以很像01揹包的感覺。因此,重點是要找到dp陣列下標和數值含義以及狀態轉移方程。
神奇的思路在於,當dp[j]下標j表示當前子集的和為j,數值代表有多少個和為j的子集,那麼dp[j]=dp[j]+dp[j-i] ,這個i就是當前我應該放入的數。
分析:每個數字只用到一次,每種情況的存在數可以由之前的存在的數來遞推得到,01揹包的變形。
#include#includeusing namespace std;
int allsum=0;
int cnt=0;
int n;
long long dp[10000];
int main()
dp[0]=1; //!!!!空集也是集合!,重點是下面的迴圈裡當j=i時,dp[i]+=dp[0]的含義就是乙個子集只要i乙個就行,所以算乙個方案數 加上。
for(int i=1;i<=n;i++) //向背包中(一定)放入i
}cout<
等和的分隔子集 DP
曉萌希望將1到n的連續整數組成的集合劃分成兩個子集合,且保證每個集合的數字和是相等。例如,對於n 3,對應的集合能被劃分成 和 兩個子集合.這兩個子集合中元素分別的和是相等的。對於n 3,我們只有一種劃分方法,而對於n 7時,我們將有4種劃分的方案。輸入包括一行,僅乙個整數,表示n的值 1 n 39...
動態規劃 等和的分隔子集
題目 曉萌希望將1到n的連續整數組成的集合劃分成兩個子集合,且保證每個集合的數字和是相等。例如,對於n 3,對應的集合能被劃分成 和 兩個子集合.這兩個子集合中元素分別的和是相等的。對於n 3,我們只有一種劃分方法,而對於n 7時,我們將有4種劃分的方案。輸入包括一行,僅乙個整數,表示n的值 1 n...
動態規劃 等和的分隔子集
曉萌希望將1到n的連續整數組成的集合劃分成兩個子集合,且保證每個集合的數字和是相等。例如,對於n 3,對應的集合能被劃分成 和 兩個子集合.這兩個子集合中元素分別的和是相等的。對於n 3,我們只有一種劃分方法,而對於n 7時,我們將有4種劃分的方案。輸入包括一行,僅乙個整數,表示n的值 1 n 39...