hdu 1584 蜘蛛纸牌

题意:小牌叠在大牌上,问叠成一堆的最小移动距离

思路:将所有状况进行一次DFS

 

 

 

 

 

 

 

 

#include<bits/stdc++.h>
using namespace std;
int a[11];
int s;
int vis[11];
void dfs(int k,int ans)
{
if(ans>s)return ;//优化
if(k==10)//出口
{
if(ans<s)
s=ans;
return;
}
for(int i=1;i<=9;i++)//对函数10个情况进行穷举
{
if(!vis[i])
{vis[i]=1;//对已经用过的标记
for(int j=i+1;j<=10;j++)//对结果进行处理,这里是找到就处理,再跳出。
{
if(!vis[j])
{
dfs(k+1,ans+((j-i)>0?j-i:i-j));//缩小范围,在此举例子
break;
}

} vis[i]=0;//在这个用过后进行回溯,注意实在和子问题的下面,不能出范围,
}

}

}
int main()
{
int n;
cin>>n;
while(n--)
{
s=6555535;
int i; memset(vis,0,sizeof(vis));
for(i=1;i<=10;i++)//储存方式的改变·~~
{
int b;
cin>>b;
a[b]=i;;
}
dfs(1,0);
cout<<s<<endl;
}
return 0;
}

 

 

 

区间dp

 

 

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

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

int main()
{
	int i,j,k,t,temp,len;
	scanf("%d",&t);
	while(t--)
	{
		memset(a,0,sizeof(a));
		for(i=1;i<=10;i++)
		{
			scanf("%d",&temp);
			a[temp]=i;
		}
		memset(dp,0,sizeof(dp));
		for(len=1;len<=9;len++)
		{
			for(i=1;i+len<=10;i++)
			{
				dp[i][i+len]=dp[i][i+len-1]+abs(a[i+len]-a[i+len-1]);
				for(j=i+1;j<i+len;j++)
				{
					dp[i][i+len]=min(abs(a[i+len]-a[j-1])+dp[j][i+len]+dp[i][j-1],dp[i][i+len]);
				}
			}
		}
		printf("%d\n",dp[1][10]);
	}
	return 0;
}


这道题实际上是考dp的,,,经典简单dp
posted @ 2017-03-31 14:21  地对地导弹2  Views(171)  Comments(0)    收藏  举报