背景
外星人完成对S国的考察后,准备返回,可他们的飞碟已经没燃料了……
S国的专家暗自窃喜……复仇的机会终于来了——他们打算敲诈外星人一大笔钱……
描述
S国有n个燃料基地,保存有外星人所需的全部燃料,编号分别为1,2,3,…,n,对于每个燃料基地i,都有【((i-1) mod 10)+1】吨燃料。其中,编号<=5的燃料基地两两之间都有可双向通行的路;对于其余每个燃料基地i,与(i-1),(i-3)之间,也有可双向通行的路。对于任意两燃料基地i,j,若之间有路将他们【直接】连接,则通过这条路的运费为【(i*j)mod10+(i+j)mod6+1)】(单位:元/吨)。
S国的专家要按每吨一元的价格把燃料卖给外星人,并且要它们支付运费。那么,外星人应选择把所有燃料运往那个燃料基地,才能尽可能的让S国专家失望?它们所要支付的最小费用是多少?
注:数据保证解的唯一性。
输入格式
仅有一个整数n。
输出格式
第一行:外星人所要支付的最小费用;
第二行:可供外星人选择的燃料基地的编号。
测试样例1
输入
6
输出
107
5
备注
样例解释:
第1-5个基地两两间有路,第6个基地与第3,5个基地间有路。当把全部燃料运到第五个基地时,总费用最少,为107.
数据范围:
对于 30%的数据,有5<N<50;
对于 60%的数据,有5<N<500;
对于100%的数据,有5<=N<700;
输出数据范围请大家自行判断。
题解
700弱数据。。谨遵黄学长教诲,用来练打表了
大致程序就是这样,两次打表第二遍输出j就行了
#include<cstdio> #include<algorithm> #include<cstring> #define inf 1<<29 using namespace std; int a[710],map[710][710]; int link[710][710],b[710]; void floyd(int x) { for(int k=1 ; k<=x ; ++k) for(int i=1 ; i<=x ; ++i) for(int j=1 ; j<=x ; ++j) if(link[i][k]<link[i][j]&&link[k][j]<link[i][j]) link[i][j]=min(link[i][j],link[i][k]+link[k][j]); } int main() { memset(map,0x7f,sizeof(map)); for(int i=1 ; i<=700 ; ++i){a[i]=((i-1)%10)+1;b[i]=b[i-1]+a[i];} for(int i=1 ; i<=700 ; ++i) { map[i][i]=0; if(i<=5) { for(int j=i+1 ; j<=5 ; ++j) { int t=(i*j)%10+(i+j)%6+1; map[i][j]=map[j][i]=t; } } else { int t=(i*(i-1))%10+(i+i-1)%6+1; map[i][i-1]=map[i-1][i]=t; t=(i*(i-3))%10+(i+i-3)%6+1; map[i][i-3]=map[i-3][i]=t; } } for(int i=1 ; i<=700 ; ++i) { int ans=inf; for(int j=1 ; j<=i ; ++j) for(int k=1 ; k<=i ; ++k) link[j][k]=map[j][k]; floyd(i); for(int j=1 ; j<=i ; ++j) { int tmp=0; for(int k=1 ; k<=i ; ++k) { tmp+=link[j][k]*a[k]; } ans=min(ans,tmp+b[i]);
/* if(ans>tmp+b[i])
{
ans=tmp+b[i];
fu=j;
}
}
printf("%d,",fu);
}*/第二个表 printf("%d,",ans); } return 0; }