Time Limit : 1000/500ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)數組
Problem Descriptionide
Due to the preparation to the wedding you have to fill up M balloons. There are N volunteers and one device for balloons filling up. Device can fill at most one balloon at a time. Each volunteer can continuously operate the device for 1 minute.
Volunteer number i can fill Ai balloons during one minute and then he or she must have at least Bi minutes of rest.
You are to write a program that computes minimal possible time of filling up M balloons.ui
Input
There are two integers M and N on the first line (1 <= M <= 100, 1 <= N <= 10).
Next N lines contain two integers each: Ai and Bi (0 <= Ai <= 10, 1 <= Bi <= 4).spa
Output
Print one integer T - the minimal number of minutes required to filling M balloons.rest
Sample test(s)code
Input
10 3
4 4
3 4
2 3排序
Output
5ip
題意:N(1<=N<=10)我的一臺裝置填充M(1<=M<=100)個氣球,每一個人一分鐘能充Ai個(0<=Ai<=10),休息Bi(1<=Bi<=4)分鐘後才能夠繼續充氣球,文填充M個氣球最少須要多少時間?
分析:看到題目,第一想法就是排序,先大後小,而後DFS,這樣顯然錯的,樣例都過不了,而後又想着暴力寫出來,不行,確定會超時,只給了0.5s。
而後無奈看了大佬寫的博客,他就直接觀察到了Bi的範圍,是1到4,這個很小,能夠開一個五維數組ans[sum][a][b][c][d]來表示還剩sum個氣球,前一分鐘是a在充氣球,前兩分鐘是b在充氣球,前3分鐘是c在充氣球,前4分鐘是d在吹氣球,而後直接記憶化搜索博客
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=11,INF=0x3f3f3f3f; int ans[101][N][N][N][N],A[N],B[N]; int n,m,res; int dfs(int sum,int a,int b,int c,int d) { if(sum<=0) sum=0;///所有充完 if(ans[sum][a][b][c][d]!=INF) return ans[sum][a][b][c][d];///還剩sum個球所用的最短期已找到 if(sum==0) ans[sum][a][b][c][d]=0;///所有填充完畢 else { int flag=0; for(int i=1; i<=n; i++) { if(a==i&&B[i]>0) continue; if(b==i&&B[i]>1) continue; if(c==i&&B[i]>2) continue; if(d==i&&B[i]>3) continue; flag=1; int t=dfs(sum-A[i],i,a,b,c);///第i人在充氣球 ans[sum][a][b][c][d]=min(ans[sum][a][b][c][d],t+1);///+1是由於最後還有一我的在充 } if(!flag)///都在休息 { int t=dfs(sum,0,a,b,c); ans[sum][a][b][c][d]=min(ans[sum][a][b][c][d],t+1); } }; return ans[sum][a][b][c][d]; } int main() { scanf("%d%d",&m,&n); memset(ans,INF,sizeof(ans)); for(int i=1; i<=n; i++) scanf("%d%d",&A[i],&B[i]); res=dfs(m,0,0,0,0); printf("%d\n",res); return 0; }
寫這題的時候那個oj的判題有問題,我寫錯了一個地方,致使樣例都過不了,還AC了。。。。。 不過這個思路應該沒問題
若有不對的地方,煩請大佬指出,謝謝
小結:像這類題,觀察數據範圍,好比數組B,範圍小,就能開一個數組記憶最少時間,而後和DFS結合。
本身對記憶化搜索不太感冒,還要勤加練習。string