LightOJ 1223 Testing Mailboxes(区间)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1223

题意:有n个箱子,箱子有个承受炸弹的属性,比如箱子被x个炸弹一起炸不会坏但是被x+1个炸弹炸会坏掉,我们就说箱子承受能力E为x。现在我们知道箱子的E最大为m,但是不是确切地知道箱子的E值。现在给你n个箱子让你准确测出箱子的E值(每个箱子的E值相同,箱子一旦被炸掉就不能在再用了,但是没有被炸坏的话可以继续测试)。问在最坏情况下最少要用几个炸弹?

思路:f[x][L][R]表示用x个箱子准确测出[L,R]区间的E所用的最少炸弹,f[x][L][R]=min(i+max(f[x-1][L][i-1],f[x][i+1][R]))(L<=i<=R),即先测i个炸弹的,若箱子被炸坏,则为1+f[x-1][L][i-1],否则为1+f[x][i+1][R]。。。。

 

 

View Code
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #define max(x,y) ((x)>(y)?(x):(y))

 5 #define min(x,y) ((x)<(y)?(x):(y))

 6 using namespace std;

 7 

 8 

 9 const int INF=1000000000;

10 int C,num=0;

11 int f[105][105][105],n,m;

12 

13 

14 int DFS(int x,int L,int R)

15 {

16     if(L>R) return 0;

17     int &ans=f[x][L][R],i;

18     if(ans!=-1) return ans;

19     ans=INF;

20     for(i=L;i<=R;i++) ans=min(ans,i+max(DFS(x-1,L,i-1),DFS(x,i+1,R)));

21     return ans;

22 }

23 

24 void init()

25 {

26     memset(f,-1,sizeof(f));

27     int i,j,k;

28     for(i=1;i<=100;i++) for(j=i;j<=100;j++) f[1][i][j]=(i+j)*(j-i+1)/2;

29     for(i=2;i<=100;i++) for(j=1;j<=100;j++) for(k=j;k<=100;k++)

30         DFS(i,j,k);

31 }

32 

33 int main()

34 {

35     init();

36     for(scanf("%d",&C);C--;)

37     {

38         scanf("%d%d",&m,&n);

39         printf("Case %d: %d\n",++num,f[m][1][n]);

40     }

41     return 0;

42 }

 

 

 

 

你可能感兴趣的:(mail)