Problem 2120 数字排列
Accept: 38 Submit: 176
Accept: 38 Submit: 176
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
S得到了一个数,他认为相邻位上的数字与数字之间会产生不良影响,比如123,1和2之间产生一个不良影响值,2和3之间产生一个不良影响值。现在他想调整这个数每位的数字的顺序,使得最终得到的数的总的不良影响值最小,且没有前导0。
Input
输入数据的第一行为T表示有T组数据。每组数据先输入一个整数n(0<n<1000000000),接下来输入10*10的矩阵,Aij表示数字i与数字j相邻产生的不良影响值,0<Aij<1000000,矩阵是对称的,Aij与Aji相等。
Output
对于每组数据输出一行一个数,表示最小的不良影响值。
Sample Input
1 123 0 0 0 0 0 0 0 0 0 0 0 0 10 1 0 0 0 0 0 0 0 10 0 2 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sample Output
3
Source
FOJ有奖月赛-2013年4月(校赛热身赛)
这是一道TSP的变种题,由于不大于12,故用DFS+剪枝可以过
没啥好讲的,就是不能有前导0,囧,刚开始不认真读题,WA得不知所措
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[11][11],v[11],a[11];
int mx,mn,n,ans;
void dfs(int x,int cost,int k){//id 花费 个数
if(k==n){ans=min(ans,cost);return ;}
if(cost+(n-k)*mn>=ans)return;//剪枝
for(int i=0;i<n;i++){
if(v[i]==1)continue;
v[i]=1;
dfs(a[i],cost+map[x][a[i]],k+1);
v[i]=0;
}
}
int main(){
int T;
char ch[11];
cin>>T;n=0;
while(T--){
//cout<<"start"<<endl;
//while((c=getchar())!='\n')a[n++]=c-'0';
cin>>ch;n=strlen(ch);
for(int i=0;i<n;i++)a[i]=ch[i]-'0';
mn=100000000;mx=-1;ans=0;
for(int i=0;i<10;i++)
for(int j=0;j<10;j++){
cin>>map[i][j];
if(map[i][j]!=0){
mn=min(map[i][j],mn);
mx=max(map[i][j],mx);
ans+=map[i][j];
}
}
if(mx==mn)ans=(n-1)*mn;//如果全部相等,ans=(n-1)*mx
else {
for(int i=0;i<n;i++){
if(a[i]==0)continue;
memset(v,0,sizeof(v));
v[i]=1;
dfs(a[i],0,1);
}
}
cout<<ans<<endl;
}
return 0;
}