题目链接:
题目大意:
给出k个油桶,给出油桶被炸掉的最小限度的上限,问在最坏情况下需要炸药最少的决策条件下需要的炸药。
题目分析:
首先定义状态dp[i][j][k]是还剩i个油桶且当前需要进行判断的区间是j-k的时候的最优值,这样的话dp[i][j][k]的情况一定是最坏的我们不能决定,但我们能够进行决策,也就是我们能够确定在当前状态下选择检验的量,对于每个选择的检验量,会有两种情况,第一种情况是油桶的最小承受限度小于检验量,那么这个油桶就炸掉了,那么就是转移到dp[i-1][j][t-1]+t,另一种情况最小承受限度大于检验量,那么这个油桶还在,同样我们的检测区间也变小了,也就是转移到dp[i][t+1][k],因为是在最坏情况下,所以要在两种情况中取较大的,然后因为要通过决策得到最优解,也就是最小值,所以枚举t求解最小值
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 107
#define INF 1<<29
using namespace std;
int n,k,m;
int dp[20][MAX][MAX];
void init ( )
{
memset ( dp , 0 , sizeof (dp));
for ( int i = 1 ; i < MAX ; i++ )
for ( int j = i ; j < MAX ; j++ )
dp[1][i][j] = (j-i+1)*(i+j)/2;
for ( int i = 2 ; i <= 10 ; i++ )
for ( int j = 1 ; j <= 100 ; j++ )
for (int k = j; k > 0 ; k-- )
{
dp[i][k][j] = INF;
for ( int t = k ; t <= j ; t++ )
dp[i][k][j] = min ( dp[i][k][j] ,
max ( dp[i-1][k][t-1]+t , dp[i][t+1][j]+t ));
}
}
int main ()
{
init();
scanf ( "%d" , &n );
while ( n-- )
{
scanf ( "%d%d" , &k , &m );
printf ( "%d\n" , dp[k][1][m] );
}
}