雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

环形dp——石子合并[NOI1995]

Posted on 2011-08-02 18:13  huhuuu  阅读(1658)  评论(0编辑  收藏  举报
经典的dp,对我这种菜鸟有难度啊。。。
由于石头可以围成一个环,所以要原来数据*2
用记忆化搜索,其实就是dp
View Code
#include<stdio.h>
#include
<string.h>

int a[209];
int maxdp[209][209];
int mindp[209][209];
int sum[209][209];

int max(int a,int b)
{
if(a>b)return a;
else return b;
}
int min(int a,int b)
{
if(a>b)return b;
else return a;
}


int dfs(int ll,int rr)
{
if(rr-ll==0)return 0;

if(maxdp[ll][rr]!=0)return maxdp[ll][rr];
int i,Max=0;
for(i=ll;i<rr;i++)
{
int t=sum[ll][rr]+dfs(ll,i)+dfs(i+1,rr);
if(Max<t)
Max
=t;
}
return maxdp[ll][rr]=Max;
}

int mdfs(int ll,int rr)
{
if(rr-ll==0)return 0;

if(mindp[ll][rr]!=0)return mindp[ll][rr];
int i,Min=99999999;
for(i=ll;i<rr;i++)
{
int t=sum[ll][rr]+mdfs(ll,i)+mdfs(i+1,rr);
if(Min>t)
Min
=t;
}
return mindp[ll][rr]=Min;
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,j;
memset(maxdp,
0,sizeof(maxdp));
memset(mindp,
0,sizeof(mindp));
memset(sum,
0,sizeof(sum));

for(i=1;i<=n;i++)
{
scanf(
"%d",&a[i]);
a[n
+i]=a[i];
}

for(i=1;i<=2*n;i++)
{
for(j=i;j<=2*n;j++)
{
sum[i][j]
=sum[i][j-1]+a[j];
}
}
int temp=9999999;
for(i=0;i<=n;i++)
{
temp
=min(temp,mdfs(1+i,n+i));
}

int temp2=0;
for(i=0;i<=n;i++)
{
temp2
=max(temp2,dfs(1+i,n+i));
}
printf(
"%d\n%d\n",temp,temp2);
}
}