E Elevators in Jiayuan Students' Apartment

E  Elevators in Jiayuan Students' Apartment

 Description

There are three elevators in the Building Bof Jiayuan Students' Apartment in BJTU, which carry a lot of students to go upand down every day.

There're 16 floors in the Building B. Thestudents living on the 1F don't need to wait for the elevators, so all the mstudents want to get to the 2F or higher.

Supposed that the capacity of each elevatoris C( 1 ≤ C ≤ 13 ). Now there are m( 1 ≤ m ≤ 3*C ) students waitingfor upstairs on the first floor, while all the three elevators stop on thefirst floor. You can arrange the way how they go upstairs, that Nobody willleft on the first floor when the elevators are in the process of rising. Howmany times do the three elevators have to stop at least to carry all the mstudents to the right floor?

Input

The first line of input contains a numbert, which means there are t cases of the test data.

In each case of testing data, the firstline contains two integers C and m.

In the next line, there are m integers f (2 ≤ f ≤ 16 ), indicate the floor a student wants to reach.

Output

For each case of testing data, the firstline is written as "Case n: X", where n is the case number, X is theminimum times the elevators have to stop in the process of rising.

Sample Input

2

1 3

2 4 16

2 6

9 9 9 6 6 6

Sample Output

Case 1: 3

Case 2: 4

時隔半年之久,第一次寫了道DP問題。想了許久,一直以爲是搜索,腦海中根本壓根就沒DP的影子!

參考了標程後感慨——這真是一道相當經典的題目啊!可惜自己沒能寫出來,感覺真的很遺憾!

dp[f][x+u][y+v][z+data[f]-u-v] 

= min{dp[f-1][x][y][z]+(u!=0)+(v!=0)+((data[f]-u-v)!=0), dp[f][x+u][y+v][z+data[f]-u-v]} 

其中dp[f][x][y][z]表示到達樓層f,三人電梯人數分別爲x、y、z時的最優解!

data[f]表示去樓層f的人數!

DP問題嘛,給你狀態存儲數組,給個狀態轉移方程。夠了!

hehe...

#include<iostream>
#include<cstdio>
using namespace std;

int dp[20][20][20][20];

int main()
{
    int i,j,k;
    int cases;
    scanf("%d", &cases);
    int t = 1;
    while(t <= cases)
    {
            int c,m;
            scanf("%d %d", &c, &m);
            int layer[20];
            memset(layer, 0, sizeof(layer));
            for(i=0; i<m; i++)
            {
                     cin>>k;
                     layer[k] ++;
            }
                     
                     memset(dp, -1, sizeof(dp));
                     int f,x,y,z,u,v;
                     dp[1][0][0][0] = 0;
                     for(f=2; f<=16; f++)
                     for(x=0; x<=c; x++)
                     for(y=0; y<=c; y++)
                     for(z=0; z<=c; z++)
                     {
                              if(dp[f-1][x][y][z] == -1) continue;
                              for(u=0; u<=layer[f]; u++)
                              for(v=0; v<=layer[f]; v++)
                              {
                                  if(u+v>layer[f]) continue;
                                  if(x+u>c||y+v>c||z+layer[f]-u-v>c) continue;
                                  int tmp = 0;
                                  tmp = dp[f-1][x][y][z]+(u!=0)+(v!=0)+((layer[f]-u-v)!=0);
                                  if(dp[f][x+u][y+v][z+layer[f]-u-v] == -1 || dp[f][x+u][y+v][z+layer[f]-u-v] > tmp)
                                  dp[f][x+u][y+v][z+layer[f]-u-v] = tmp; 
                                   }                             
                              }
                              
                              int res = 10000000;
                              for(i=0; i<=c; i++)
                              for(j=0; j<=c; j++)
                              if(i+j <=c && dp[16][i][j][m-i-j] < res && dp[16][i][j][m-i-j] != -1)
                              res = dp[16][i][j][m-i-j];
                              cout<<"Case "<<t<<": "<<res<<endl;
                    
            }
            return 0;
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章