您的位置:首页 > 其它

uva103(最长递增序列,dag上的最长路)

2015-04-03 21:14 489 查看
题目的意思是给定k个盒子,每个盒子的维度有n dimension

问最多有多少个盒子能够依次嵌套

但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明

盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中

这个题目能够转化为最长递增子序列。

首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排序

这样中的目的是,后面的盒子一定放不到前面的盒子里面,这样是为了消除无后效性。

如果不排序,那么将有后效性,比如第一个盒子不选,但是第二个盒子可以放到第一个盒子里面。

然后就转化为最长递增序列的问题了。

/*
建图(dag图),
拓扑排序
dp
*/

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
using namespace std;
const int INF = 1<<30;
struct node
{
int dimension[10];

}a[33];
bool canInput[33][33];//canInput[i][j]判断i能不能放到j里面去
int dp[100];
int path[33];
int ans[100];
int in[30];
int sequeue[30];
int main()
{
int n,k,i,j,z;
while(scanf("%d%d",&k,&n)!=EOF)
{
memset(ans,0,sizeof(ans));
memset(canInput,false,sizeof(canInput));
memset(dp,0,sizeof(dp));
memset(in,0,sizeof(in));
for(i=0; i<k; ++i)
{
dp[i] = 1;
path[i] = i;
for(j=0; j<n; ++j)
{
scanf("%d",&a[i].dimension[j]);
}
sort(a[i].dimension,a[i].dimension+n);
}

for(i=0; i<k; ++i)//预处理,建图
for(j=i+1; j<k; ++j)
{
bool can = true;
for(z=0; z<n; ++z)
{
if(a[i].dimension[z] >= a[j].dimension[z])
can = false;
}
if(can)
canInput[i][j] = true;
can = true;
for(z=0; z<n; ++z)
{
if(a[i].dimension[z] <= a[j].dimension[z])
can = false;
}
if(can)
canInput[j][i] = true;

}
//每个结点的入度
for(i=0; i<k; ++i)
{
for(j=0; j<k; ++j)
if(canInput[i][j])
in[j]++;
}
//拓扑排序,sequeue数组存在排序之后的序列
for(i=0; i<k; ++i)
{
for(j=0; in[j]&&j<k; ++j)
NULL;
in[j] = -1;
sequeue[i] = j;
for(z=0; z<k; ++z)
if(canInput[j][z])
in[z]--;
}

//对拓扑排序之后的序列进行最长递增子序列的dp
for(i=0; i<k; ++i)
for(j=0; j<i; ++j)
{
if(canInput[sequeue[j]][sequeue[i]] && dp[j]+1>dp[i])//sequeue[i]
{
dp[i] = dp[j]+1;
path[i] = j;
}
}
int cnt = 0,index;
for(i=0; i<k; ++i)
if(cnt < dp[i])
{
cnt = dp[i];
index = i;
}
printf("%d\n",cnt);

ans[--cnt] = index;
while(path[index] != index)
{
ans[--cnt] = path[index];
index = path[index];
}
//sequeue[i]
printf("%d",sequeue[ans[cnt++]]+1);
while(ans[cnt]!=0)
{
printf(" %d",sequeue[ans[cnt++]]+1);
}
puts("");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: