巡回演出

题目点这里~https://blog.csdn.net/fisher_jiang/article/details/810358

题目长到恐怖。。。

然而80%在讲输入。。。(手动吐血)

其实一道较典型的dp

直接上代码啦:(没地方测,可能应该大概能ac)

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct node
{
	int zq[30+5],len;//周期第i天为zq[i] ,长度为len 
};

const int maxValue=0x7fffffff;
int n,k1;
node a[10+5][10+5];//a[i,j]:从i到j的旅程表 
int f[10+5][1000+5];//f[i,j]:第j天到第i个城市最小花费,=-1为不存在 

void dp()
{
	int i,j,k,k2;
	
	f[1][0]=0;
	for (k=1;k<=k1;k++)//第k天 
	{
		for (i=1;i<=n;i++)//起始城市 
		{
			if (f[i][k-1]<0) 
				continue;
			for (j=1;j<=n;j++)//目标城市 
			{
				if (i==j)
					continue;
				k2=k%a[i][j].len;
				if (a[i][j].zq[k2]==0)
					continue;
					
				if (f[j][k]==-1)
					f[j][k]=maxValue;
				f[j][k]=min(f[j][k],f[i][k-1]+a[i][j].zq[k2]);
			}
		}
	}
	if (f[n][k1]==-1)
		printf("0\n");
	else
		printf("%d\n",f[n][k1]);
}

int main()
{
	int i,j,k,x,y;
	
	freopen("a.txt","r",stdin);
	while (1)
	{	
		scanf("%d%d",&n,&k1);
		if (n==0)
			break;
		for (i=1;i<=n;i++)
			for (j=0;j<=k1;j++)
				f[i][j]=-1;
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=n;j++)
			{
				if (j==i)
					j++;
				if (j>n)
					break;
					
				scanf("%d",&x);//周期长度
				a[i][j].len=x;
				for (k=1;k<=x;k++) 
				{
					scanf("%d",&y);
					if (k==x)
						a[i][j].zq[0]=y;
					else 
						a[i][j].zq[k]=y;
				}
//				for (k=1;k<=x;k++)	printf("%d ",a[i][j].zq[k]);
//				printf("\n");
			}
		}
		dp();
	}
	
	
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/scutbenson/article/details/82055154