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

浙公网安备 33010602011771号