[CF805C] Find Amir(贪心,构造,模拟)

本文介绍了解决 CodeForces 805C 问题的方法,该问题要求找到遍历 n 个节点的最小总花费,其中从 i 到 j 的花费由 (i+j)%(n+1) 计算得出。文章提供了两种解决方案,一种通过构造特定路径来减少花费,另一种则是直接利用观察到的规律简化问题。

题目链接:http://codeforces.com/contest/805/problem/C

题意:n个数,从i到j的花费为(i+j)%(n+1),问n个数都要走一遍,求最小花费。

希望尽可能地让i+j是n+1的倍数,所以构造:从1开始,那么下一个点必为n,因为(1+n)%(1+n)=0为最小花费,从n则可以到2,没办法,只能花费1。以此类推反复横跳。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 100100;
 5 int n, a[maxn];
 6 bool vis[maxn];
 7 
 8 int main() {
 9     // freopen("in", "r", stdin);
10     while(~scanf("%d", &n)) {
11         memset(vis, 0, sizeof(vis));
12         int mod = n + 1;
13         int ret = 0, cnt = 1;
14         int cur = 1;
15         int lo = 2;
16         vis[cur] = 1;
17         while(cnt <= n) {
18             if(!vis[mod-cur]) {
19                 vis[mod-cur] = 1;
20                 cur = mod - cur;
21             }
22             else {
23                 vis[lo] = 1;
24                 cur = lo;
25                 lo++;
26                 ret++;
27             }
28             cnt++;
29         }
30         printf("%d\n", ret-1);
31     }
32     return 0;
33 }

 

???找规律发现,这答案直接输出(n-1)/2就行了。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 100100;
 5 int n, a[maxn];
 6 bool vis[maxn];
 7 
 8 int main() {
 9     // freopen("in", "r", stdin);
10     while(~scanf("%d", &n)) {
11         printf("%d\n", (n-1)/2);
12     }
13     return 0;
14 }

 

转载于:https://www.cnblogs.com/kirai/p/6856790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值