ACM预备队-week6(贪心)
[NOIP2010 普及组] 三国游戏
题目链接:P1199 [NOIP2010 普及组] 三国游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
就是考脑子,,小涵拿不到最大的默契值,同时计算机也拿不到,最大的那一对一定会被两方拆散,所以小涵每次可以拿到次大的最佳武将组合,记为(i,j),不妨设(i,k),(j,l)分别为两对最佳匹配。
第一步,小涵拿i,所以计算机一定拿k,第二步,小涵拿j,计算机一定拿l,所以小涵就拿到了次大中最佳匹配的组合(i,j),而因为默契值都不相同 ,并且(k,l)不是最佳次大,所以小涵的武将默契值比电脑高,即(i,j)>(k,l)。
之后,小涵只要不让计算机拿到剩余的所有最佳匹配,则计算机至多拿到次佳。已知次佳的最大一对在小涵手里,所以小涵必胜。
因此,不能降成一维输出次大(20分),而是应该把每一行的次大取max,这才是最后答案。
相当于:小涵选全图具有最大匹配值武将之一,然后计算机拆散了,然后小涵拿到了次大武将,并且与第一次选的匹配生成了最大默契,然后计算机把视角转向了第二次选的那一行,然后重新拆散这一行的最大值,所以小涵每次就挑着具有次大max的那一行挑,就必赢
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N=510;
4 int a[N][N];
5 int ans;
6 int main()
7 {
8 ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
9 int n;
10 cin>>n;
11 for(int i=1;i<n;i++)
12 for(int j=i+1;j<=n;j++)
13 {
14 cin>>a[i][j];
15 a[j][i]=a[i][j];
16 }
17 for(int i=1;i<=n;i++)
18 {
19 sort(a[i]+1,a[i]+1+n);
20 ans=max(ans,a[i][n-1]);
21 }
22 cout<<1<<endl;
23 cout<<ans;
24 }
独木桥
碰面立马掉头的含义其实就是可以灵魂穿透,类似于将军饮马把同侧转化成了异侧直线的意思,换言之,这与他们相互穿过并没有任何区别。
对于每一个士兵,都有向左向右两种选择,设士兵在位置x,如果向左,需要x时间单位;向右,需要L-x+1个。分别取max和min,更新答案即可。
1 #include <bits/stdc++.h>
2 using namespace std;
3 int MAX,MIN;
4 int main()
5 {
6 ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
7 int l,n;
8 cin>>l>>n;
9 for(int i=1;i<=n;i++)
10 {
11 int x;//起始坐标
12 cin>>x;
13 MAX=max(MAX,max(x,l-x+1));
14 MIN=max(MIN,min(x,l-x+1));
15 }
16 cout<<MIN<<' '<<MAX;
17
18 }
排队接水
题目链接:P1223 排队接水 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
排序不等式,对于每一个人,都有一个接水时间,后面的人要想接水就必须等待前面这个人的时间,即第一个人让后面的n-1人共等待了(n-1)×第一个人打水时间。
比如,三个人,3 2 1 分别表示打水时间,所以对于每个人打水时间就是 0 3 (3+2),所以可以得出公式:T总=∑(n-i)*t[i]
所以越前面的人打水时间越少(前面的权重越小),打水总时间越少。注意,如果数据是1e5,就有可能爆int,所以干脆直接开long long
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N=1010;
4 typedef long long LL;
5 struct fun
6 {
7 int num;
8 int val;
9 }t[1010];
10 bool cmp(fun a,fun b)
11 {
12 return a.val<b.val;
13 }
14 int main()
15 {
16 int n;
17 cin>>n;
18 for(int i=1;i<=n;i++)
19 {
20 cin>>t[i].val;
21 t[i].num=i;
22 }
23 double res=0;
24 sort(t+1,t+1+n,cmp);
25 for(int i=1;i<=n;i++)
26 {
27 cout<<t[i].num<<' ';
28 res+=t[i].val*(n-i);
29 }
30 cout<<endl;
31 cout<<fixed<<setprecision(2)<<res/n;
32 return 0;
33 }
[NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G
题目链接:P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
经典Huffman树问题(合并的图相当于一颗完全二叉树)
每次合并重量最小的两堆果子即可。
时间复杂度
使用小根堆维护所有果子,每次弹出堆顶的两堆果子,并将其合并,合并之后将两堆重量之和再次插入小根堆中。
每次操作会将果子的堆数减一,一共操作 n−1 次即可将所有果子合并成1堆。每次操作涉及到2次堆的删除操作和1次堆的插入操作,计算量是 O(logn)。因此总时间复杂度是 O(nlogn)。
1 #include <bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int n;
6 cin>>n;
7 priority_queue<int,vector<int>,greater<int> >q;
8 while(n--)
9 {
10 int x;
11 cin>>x;
12 q.push(x);
13 }
14 int res=0;
15 while(q.size()>1)
16 {
17 int a,b;
18 a=q.top(),q.pop();
19 b=q.top(),q.pop();
20 res+=a+b;
21 q.push(a+b);
22 }
23 cout<<res;
24 }
本文作者:Zac-saodiseng
本文链接:https://www.cnblogs.com/Zac-saodiseng/p/16952891.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步