Google Code Jam 2009 round C

Google Code Jam 2009 round C
转自; http://blog.csdn.net/masterluo
记忆化DP。对于要取得最优值,假设应该释放的排列为Q1, Q2, ……, Qn,我们在第一次分割后,1-P分解成二个子问题,1-(Q1-1)与(Q1+1)-P,这样就把问题分划为更小的问题,再递归进行求解,然而在递归的过程中,许多问题被重复计算,我们可以把己经计算出来的区间最小值记录下来,以后每次进行分割时,如果某个段己经求得最值就直接返回,否则进行递归查找。




#include 
< stdio.h >
#include 
< map >
using   namespace  std;
const   int  maxn = 110 ;
int  p,q;
int  id[maxn];
map
< pair < int , int > , int > mp;
int  solve( int  l, int  r)
{
    pair
< int , int > pr(l,r);
    
if (mp.find(pr) != mp.end())
    {
        
return  mp[pr];
    }
    
int  ans =- 1 ;
    
for ( int  i = 0 ;i < q;i ++ )
    {
        
if (id[i] >= &&  id[i] <= r)
        {
            
int  tmp = r - l + solve(l,id[i] - 1 ) + solve(id[i] + 1 ,r);
            
if (ans ==- 1   ||  tmp < ans)
                ans
= tmp;
        }
    }
    
if (ans ==- 1 ) ans = 0 ;
    mp[pr]
= ans;
    
return  ans;
}
int  main()
{
    freopen(
" in " , " r " ,stdin);
    freopen(
" myout " , " w " ,stdout);
    
int  t;
    scanf(
" %d " , & t);
    
for ( int  i = 1 ;i <= t;i ++ )
    {
        mp.clear();
        scanf(
" %d%d " , & p, & q);
        
for ( int  j = 0 ;j < q;j ++ )
            scanf(
" %d " , & id[j]);
        printf(
" Case #%d: %d\n " ,i,solve( 1 ,p));
    }
    
return   0 ;
}

你可能感兴趣的:(Google Code Jam 2009 round C)