http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=3555&cid=1755
小白の人品测试
Time Limit: 1000MS Memory limit: 65536K
题目描述
现在有n个人,编号从1到n ,每个人有一个 人品值
这是一个赤裸裸的金钱关系的世界
如果小白想要小黑直接帮他一个忙,他需要支付的代价为 abs(小白的人品 - 小黑的人品)。
小白也可以找小金,然后小金去拜托小黑帮他,这样他就要支付双份的代价,具体的,代价为
abs(小白的人品 - 小金的人品)+abs(小金的人品 - 小黑的人品)
小白还可以找多个人帮忙,不妨记为小A,小B,小C...小Z这样他要支付多份代价
abs(小白的人品 - 小A的人品)+abs(小A的人品 - 小B的人品)+...+abs(小Z的人品 - 小黑的人品)
现在问题来了,小白最少要支付多少代价才能获得小黑的帮助
输入
多组输入直到文件结束(EOF)
一个数n代表现在有n个人(2<=n<=1000)
接下来n个整数Ai代表第i个人的人品值(0<= Ai <=100)
为了方便起见,我们假设小白的标号为1,小黑的编号为n
输出
小白要支付的代价
示例输入
5 1 1 1 1 4 3 1 2 3
示例输出
3 2
提示
abs(x) 是绝对值
来源
“师创杯”山东理工大学第八届ACM程序设计竞赛
示例程序
先是DFS代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- bool vis[1000+5];
- int n, a[1000+5], m;
- int abs(int x, int y)
- {
- return x>y?(x-y):(y-x);
- }
- void dfs(int cur, int ans)
- {
- if(cur==n&&ans<m)
- {
- m=ans;
- return ;
- }
- for(int i=1;i<=n;i++)
- {
- if(!vis[i])
- {
- vis[i]=1;
- dfs(i,ans+abs(a[i],a[cur]));
- vis[i]=0;
- }
- }
- return ;
- }
- int main()
- {
- while(~scanf("%d", &n))
- {
- m=99999999;
- for(int i=1;i<=n;i++)
- scanf("%d", &a[i]);
- memset(vis,0,sizeof(vis));
- vis[1]=1;
- dfs(1,0);
- printf("%d\n", m);
- }
- return 0;
- }
然后是贪心,想到贪心估计这题也就出来了,代码很简单:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- int n, a[1000+5];
- int abs(int x, int y)
- {
- return x>y?(x-y):(y-x);
- }
- int main()
- {
- while(~scanf("%d", &n))
- {
- for(int i=1;i<=n;i++)
- scanf("%d", &a[i]);
- int cur=1, ans=abs(a[n],a[1]);
- for(int i=2;i<=n;i++)
- {
- if(abs(a[cur],a[i])+abs(a[i],a[n])<ans)
- {
- ans=abs(a[cur],a[i])+abs(a[i],a[n]);
- cur=i;
- }
- }
- printf("%d\n", ans);
- }
- return 0;
- }