p1060盒子
accepted
描述n個盒子排成一行(1<=n<=20)。你有a個紅球和b個藍球。0 <= a <= 15, 0 <= b <= 15。球除了顏色沒有任何區別。你可以將球放進盒子。乙個盒子可以同時放進兩種球,也可以只放一種,也可以空著。球不必全部放入盒子中。程式設計計算有多少種放置球的方法。
格式 輸入格式
一行,n,a,b,用空格分開。
輸出格式
一行,輸出放置方案總數。
樣例1
樣例輸入1
2 1 1
樣例輸出1
9
限制
1s方案數,又是方案數!
題目大意:給你n個排成一排的盒子,每個盒子裡面可以不放入,單放入一些紅球或者放入一些藍球,同時放入兩種球(都是若干個,注意原題說的是放入兩種球不是最多只能放兩個球哦)。然後要求的是滿足最後用的紅球不超過a個,藍球不超過b個的方案數。
演算法一:根據原題所說,用回溯暴力的模擬裝球的過程,每考慮完所有的盒子方案數就疊加1。時間複雜度不穩定 最壞是o((ab)^n) 預期得分25~30
演算法一**如下:
#include
#include
#include
#include
#include
using
namespace
std;
typedef
unsigned
long
long ll;
const
int maxn=25;
int n,a,b;
bool vis[maxn][maxn][maxn];
ll ans=0;
void run(int i,int j,int k)
//當前考慮第i個盒子的放置情況,此時已經放了j個紅球,k個藍球。
for(int a=0;a<=a-j;a++)
for(int b=0;b<=b-k;b++)//if(!vis[i][a][b])
}int main()
演算法二:方案問題,我們很容易想到遞推,根據本題的要求和」求什麼就設什麼」的原則比較容易想到狀態函式f(i,j,k)表示用不超過j個紅球,不超過k個藍球放前i個盒子的方案數。
分析第i個盒子的選擇,顯然第i個盒子可以不放球 或者 單放乙個紅球 或者 單放兩個紅球 … 或者 單放i個紅球 或者 單放乙個藍球 或者 單放兩個藍球 … 或者 單放j個藍球 或者 放乙個紅球乙個藍球 …
根據狀態轉移的思想 寫出遞推方程:
f(i,j,k)=f(i-1,j,k)+f(i-1,j,k-1)+…+f(i-1,j,0)
+f(i-1,j-1,k)+f(i-1,j-1,k-1)+…+f(i-1,j-1,0)
+… +f(i-1,0,k)+f(i-1,0,k-1)+…+f(i-1,0,0)
即f(i,j,k)+=f(i-1,x,y)| 0<=x<=j 0<=y<=k
邊界是f(0,j,k)=1
時間複雜度o(a^2*b^2*n) 預期得分100
演算法二的**實現:
#include
#include
#include
#include
#include
using namespace std;
typedef unsigned long long ll;
const int maxn=25;
int n,a,b;
ll f[maxn][maxn][maxn];
/* f(i,j,k)=在前i個盒子裡面放不多於j個紅球,不多於k個籃球的方案數.
f(i,j,k)=f(i-1,j,k)+f(i-1,j-1,k)+...+f(i-1,j,k-1)+...+f(i-1,j-1,k-1)+...
f(0,i,j)=1;
*/int main()
演算法三:優化遞推
由於a,b兩球除了顏色之外其餘的屬性都相同,不如將兩種球分別處理。
此時設f(i,j)表示選不超過j個球放入前i個盒子。
假設只有a球 f(n,a)就是n個盒子,a個紅球的方案數。
假設只有b球 f(n,b)就是n個盒子,b個紅球的方案數。
由乘法原理,最後的答案是f(n,a)*f(n,b)
同樣分析第i個盒子的情況,可以不選球,可以選乙個,可以選兩個…
對應的遞推方程:f(i,j)=f(i-1,j)+f(i-1,j-1)+f(i-1,j-2)+…+f(i-1,0)=sigma(f(i-1,x)) | 0<=x<=j
邊界分析 f(0,j)=1
這種方法的時間複雜度o(n*max(a,b)^2)
實現遞推的**:
for(int j=0; j
<=a || j
<=b ;j++)
f[0]
[j]=1;
for(int i=1;i
<=n;i++)
for(int j=0; j
<=a || j
<=b ;j++)
for(int k=0;k<=j;k++)
觀察到填表實現時f[i][j]的值其實是上一行所有f[i-1][j]的和,還可以繼續用字首和的思想優化,在列舉j的時候就算出t,然後再改變f[i][j]的值。
完整**:
#include
#include
#include
#include
#include
using
namespace
std;
typedef
unsigned
long
long ll;
const
int maxn=25;
int n,a,b;
ll f[maxn][maxn];
/* f(i,j)=在前i個盒子裡面放不多於j個球的方案數
f(i,j)=f(i-1,j)+f(i-1,j-1)+...+f(i-1,0);
ans=f(n,a)*f(n*b);
f(0,j)=1; | 0<=j<=max(a,b)
*/int main()
}cout
<'\n';
return
0;}
考試的總結:考的時候,只想到了第二種方法,資料也小,確實也能過。今天聽評講,mr.he提了乙個問題,如果n能到1000,a,b都能到500,對方案要取模怎麼辦。聯想的考的第二個題,這樣搞絕對要爆記憶體(128m),結果mr.he講了這個第三種優化方法,直接開二維就行了,時間也比三維的快,雖然寫了搜尋對拍過了,我覺得我還是沒做到一題多解,看來還是要多想啊! 習題3 10 盒子
這道題目簡單的判斷很容易對特殊情況的忽略,這裡自己想了一下與其他人不一樣的角度來做的,若是被來客看到的話,還望指點指點 給定6個矩形的長和寬wi和hi 1 wi,hi 1000,都為整數 判斷它們能否構成長方體的6個面。若能構成,就輸出possible,不能,輸出impossible。樣例輸入 13...
CSS學習 2 盒子
css2.1還包含outline屬性。與border屬性不同,輪廓繪製在元素框之上,所以它們不影響元素的大小或定位。因此輪廓有助於修復bug,因為它們不影響頁面的布局。大多數現代瀏覽器 包括ie8 支援輪廓,但是ie7和更低版本不支援輪廓。內邊距 邊框和外邊距都是可選的,預設值為零。但是,許多元素將...
NYOJ 562 盒子遊戲
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 有兩個相同的盒子,其中乙個裝了 n 個球,另乙個裝了乙個球。alice 和 bob 發明了乙個遊戲,規則如下 alice 和 bob 輪流操作,alice 先操作。每次操作時,遊戲者先看看哪個盒子裡的球的數目比較少,然後清空這個...