列表

详情


NC25351. Center Street

描述

在哈乐冰的中央大街上有N个仓买, 我们可以将其抽象为一条线段上有N个顶点,仓买在线段上是均匀分布的,也就是说1号仓买在顶点1这个位置,2号仓买在顶点2这个位置...N号仓买在N这个位置。刚开始这些仓买之间是互相不通的,为了交流,工程师们建了一些路,但是由于资金有限,并不能在两两之间建一条路,他们只能有选择的建一些路。如果两个仓买A,B满足A是B的倍数,则A,B之间可以通一条路,当然这些路是双向的,A可以到B,B可以到A

例如N=8的时候:

仓买1向所有其他仓买通一条路。

2号仓买向4,6,8号仓买通路。

3号仓买仅和6号仓买通路。

4号仓买仅和8号仓买通路。

众所周知,建路需要花费很大一笔钱,所以资本家们需要过路的人需要收取一定费用,如果仓买A,B之间通路,则过路费为元。

现在小M站在1号仓买上,他想得知他分别到达1,2,3...N号仓买的最小花费。虽然他可以直接从1号仓买到达其他仓买,但是可以通过中转的方式让花费更少。你能帮帮他吗?

输入描述

输入一个整数,表示共有N个仓买。

输出描述

一行,输出N个整数,以空格隔开,分别代表从1号仓买到其他仓买的最小花费。

示例1

输入:

8

输出:

0 1 4 5 16 13 36 21

说明:

1号到1号仓买自身,不需花费,为0

1号到2号仓买,直接到达,花费

1号到3号仓买,直接到达,花费

1号到4号仓买,直接到达花费9。但是可以先到达2,再通过2到4的路到达,花费为

1号到5号仓买,直接到达,花费16

1号到6号仓买,1->3->6,花费13

1号到7号仓买,1->7,花费36

1号到8号仓买,通过1->2->4->8,花费为21

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 188ms, 内存消耗: 9928K, 提交时间: 2019-04-27 08:52:39

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[500005];
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		dp[i]=1e18;
	dp[1]=0;
	for(int i=1;i<=n;i++)
		for(int j=2*i;j<=n;j+=i)
			dp[j]=min(dp[j],dp[i]+1ll*(j-i)*(j-i));
	for(int i=1;i<=n;i++)
		printf("%lld ",dp[i]);
} 

C++11(clang++ 3.9) 解法, 执行用时: 70ms, 内存消耗: 10084K, 提交时间: 2019-04-25 21:27:31

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll dp[500005];
int main(){
	int n;
	dp[1]=0;
	cin>>n;
	for(int i=2;i<=n;i++) dp[i]=1e18;
	for(int i=1;i<=n;i++)
		for(int j=i+i;j<=n;j+=i){
			dp[j]=min(dp[j],dp[i]+1LL*(j-i)*(j-i));
		}
		for(int i=1;i<=n;i++) cout<<dp[i]<<" ";
	return 0;
}

上一题