In Tomb-sweeping Festival, Yangsir and her friends planned to have a journey in a park. The park has N attractions which form a circle and only between adjacent attractions there is a road, so there are N roads in total. On the way to the park, Yangsir and her friends lost their way. After several twists and turns, they arrived at the park but they still didn't know which attraction they are on now.
Looking at the park's map, Yangsir wanted to know that: if they set attraction X as starting point, what is the minimum time they needed to pass all N attractions at least once? They don't need to go back to the starting attraction and the time spend on attractions are ignored.
We number the N attractions from 1 to N clockwise, and the ith road is the road between ith and (i+1)th attraction, except that the Nth road is the road between N and 1. The N roads are all undirected.
Input
There are multiple test cases. The first line of the input will be an integer T (T <= 10) indicating the number of test cases.
For each test case, the first line is only one integer N (3 <= N <= 1000), representing the number of attractions in the park. In the second line there are N positive integers separated by one space representing the time needed to pass through the ith road. All the integers above are within 1,000,000.
Output
For each test case, print "Case #t: " first, in which t is the number of the test case starting from 1. Then output N integers separated by one space which are the minimum time needed if they start from 1st attraction, 2nd attraction,..., Nth attraction.
Sample Input
1
5
4 6 5 3 7
Sample Output
Case #1: 18 19 19 20 18
分析:由于要把 N 个点都访问一遍,因而最优解必然要经过 N-1 条(种)边,且每
条(种)边至少经过一次。最优解也最多经过 N-1 条(种)边,因为经过 N-1 条
(种)边时,已经把 N 个点都访问至少一遍。因而可以枚举哪条边不走,之后
终点必然是这条边的两个端点之一。 假如起点到两个端点的距离分别是 S1, S2,
则 这 种 方 案 的 最 优 解 是 S1+S2+min(S1,S2). 以 这 个 起 点 的 最 优 解 是
min{S1+S2+min(S1,S2)}.总的复杂度为 N^2。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
const int N=1010;
int main()
{
int t,n,a[N*2];
LL sum,ans;
scanf("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf("%d",&n);
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
sum+=a[i];
}
a[0]=a[n];
a[n*2+1]=a[1];
printf("Case #%d:",ca);
for(int i=1;i<=n;i++)
{
ans=sum-a[i]<sum-a[i-1]?sum-a[i]:sum-a[i-1];
LL temp=0;
for(int c=0;c<n-2;c++)
{
temp+=a[i+c];
if(temp+sum-a[i+c+1]<ans)
ans=temp+sum-a[i+c+1];
}
temp=0;
for(int c=1;c<n-1;c++)
{
int j=i-c;
if(j<=0) j+=n;
temp+=a[j];
if(temp+sum-a[j-1]<ans)
ans=temp+sum-a[j-1];
}
printf(" %lld",ans);
}
printf("\n");
}
return 0;
}