fzu 2120 数字排列

Problem 2120 数字排列

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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值