2022/1/16总结

今日到17:48为止学习8h24m:

今天主要就是刷题了,废话也不多说,直接上题。


题目描述

观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

        7 
      3   8 
    8   1   0 
  2   7   4   4 
4   5   2   6   5 

在上面的样例中,从 7→3→8→7→5 的路径产生了最大

输入格式

第一个行一个正整数 rr ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

输出格式

单独的一行,包含那个可能得到的最大的和。

输入输出样例

输入 #1复制

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5 

输出 #1复制

30

说明/提示

【数据范围】
对于 100% 的数据,1≤r≤1000,所有输入在 [0,100] 范围内。

题目翻译来自NOCOW。

USACO Training Section 1.5

IOI1994 Day1T1

一道简单的背包题(也可以用搜索做),我认为最简单的办法是从尾部往前装,可以省去很多额外步骤。即:从树的最下方遍历每个元素,然后再向上。这样遍历完成后,可以得到从下往上的最大的值,就是答案了。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll a[1002][1002];

int main()
{
	ios::sync_with_stdio(false);
	int r;
	cin >> r;
	ll dp[r][r];
	for(int i = 0;i < r;i ++)
	{
		for(int j = 0;j <= i;j ++)
		{
			cin >> a[i][j];
			dp[i][j] = a[i][j];
		}
	}
	for(int i = r - 2;i >= 0;i --)
	{
		for(int j = 0;j <= i;j ++)
		{
			dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + a[i][j];
		}
	}
	cout << dp[0][0];
	return 0;
}

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入格式

第一行有 2 个整数 T(1≤T≤1000)和 M(1≤M≤100),用一个空格隔开,T 代表总共能够用来采药的时间,M 代表山洞里的草药的数目。

接下来的 M 行每行包括两个在 1 到 100 之间(包括 1 和 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式

输出在规定的时间内可以采到的草药的最大总价值。

输入输出样例

输入 #1复制

70 3
71 100
69 1
1 2

输出 #1复制

3

说明/提示

【数据范围】

  • 对于 30% 的数据,M≤10;
  • 对于全部的数据,M≤100。

【题目来源】

NOIP 2005 普及组第三题

一道标准的背包题,同样从后往前以得到最佳答案。从后往前进行,可以得到最后一个值为最大值。这道题的价值与空间相互独立。

#include <bits/stdc++.h>

using namespace std;

struct medicine {
	int ct, va;
};

int main()
{
	ios::sync_with_stdio(false);
	int T, M;
	cin >> T >> M;
	struct medicine med[M];
	for(int i = 0;i < M;i ++)
	{
		cin >> med[i].ct >> med[i].va;
	}
	long long dp[T + 1] = {0};
	for(int i = 0;i < M;i ++)
	{
		for(int j = T;j >= med[i].ct;j --)
		{
			dp[j] = max(dp[j], dp[j - med[i].ct] + med[i].va);
		}
	}
	cout << dp[T];
	return 0;
}

题目背景

此题为纪念 LiYuxiang 而生。

题目描述

LiYuxiang 是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同种类的草药,采每一种都需要一些时间,每一种也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是 LiYuxiang,你能完成这个任务吗?

此题和原题的不同点:

1. 每种草药可以无限制地疯狂采摘。

2. 药的种类眼花缭乱,采药时间好长好长啊!师傅等得菊花都谢了!

输入格式

输入第一行有两个整数,分别代表总共能够用来采药的时间 t 和代表山洞里的草药的数目 m。

第 2 到第 (m+1) 行,每行两个整数,第 (i+1) 行的整数 ai​,bi​ 分别表示采摘第 i 种草药的时间和该草药的价值。

输出格式

输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

输入输出样例

输入 #1复制

70 3
71 100
69 1
1 2

输出 #1复制

140

说明/提示

数据规模与约定

  • 对于 30% 的数据,保证 m≤10^3 。
  • 对于 100% 的数据,保证 1≤m≤10^4,1≤t≤10^7,且 1≤m×t≤10^7,1≤ai​,bi​≤10^4。

刚开始也没想到这道题怎么解,后来想到:只要遍历每个物品,把能装多少就装多少的状态加进去就行了。比如数据组:

5 3
6 100
3 1
1 2

我有70的时间,3种药,那么:

第一件:

塞不下

第二件:

dp[3] = dp[0] + 1 = 1;

dp[4] = dp[1] + 1 = 1;

dp[5] = dp[2] + 1 = 1;

第三件:

dp[1] = dp[0] + 2 = 2;

dp[2] = dp[1] + 2 = 4;

dp[3] = max(dp[3], dp[2] + 2) = dp[2] + 2 = 6;

dp[4] = max(dp[4], dp[3] + 2) = dp[3] + 2 = 8;

dp[5] = max(dp[5], dp[4] + 2) = dp[4] + 2 = 10;

好了结束,最佳答案即是dp[5] = 10;

放上AC代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main()
{
	ios::sync_with_stdio(false);
	ll T, M;
	cin >> T >> M;
	ll ct[M + 1], va[M + 1];
	ll dp[T + 1] = {0};
	for(ll i = 1;i <= M;i ++)
	{
		cin >> ct[i] >> va[i];
	}
	for(ll i = 1;i <= M;i ++)
	{
		for(ll j = ct[i];j <= T;j ++)
		{
			dp[j] = max(dp[j], dp[j - ct[i]] + va[i]);
		}
	}
	cout << dp[T];
	return 0;
}

题目描述

Johnny has a younger sister Anne, who is very clever and smart. As she came home from the kindergarten, she told his brother about the task that her kindergartener asked her to solve. The task was just to construct a triangle out of four sticks of different colours. Naturally, one of the sticks is extra. It is not allowed to break the sticks or use their partial length. Anne has perfectly solved this task, now she is asking Johnny to do the same.

The boy answered that he would cope with it without any difficulty. However, after a while he found out that different tricky things can occur. It can happen that it is impossible to construct a triangle of a positive area, but it is possible to construct a degenerate triangle. It can be so, that it is impossible to construct a degenerate triangle even. As Johnny is very lazy, he does not want to consider such a big amount of cases, he asks you to help him.

输入格式

The first line of the input contains four space-separated positive integer numbers not exceeding 100 — lengthes of the sticks.

输出格式

Output TRIANGLE if it is possible to construct a non-degenerate triangle. Output SEGMENT if the first case cannot take place and it is possible to construct a degenerate triangle. Output IMPOSSIBLE if it is impossible to construct any triangle. Remember that you are to use three sticks. It is not allowed to break the sticks or use their partial length.

题意翻译

题目描述

给定 4 根木棍的长度,如果它们中存在 3 根木棍可以组成三角形,输出 TRIANGLE ;如果它们无法组成三角形,但是它们中存在 3 根木棍可以组成退化的三角形(任意两边之和大于等于第三边,但是不是三角形),输出 SEGMENT ;否则,输出 IMPOSSIBLE 。

注意: 木棍不能折断,也不能只用一部分长度。

输入格式

一行 4 个整数,4 根木棍的长度。

输出格式

如果它们中存在 3 根木棍可以组成三角形,输出 TRIANGLE ;如果它们无法组成三角形,但是它们中存在3根木棍可以组成退化的三角形,输出 SEGMENT ;否则,输出 IMPOSSIBLE

By @PC_DOS

输入输出样例

输入 #1复制

4 2 1 3

输出 #1复制

TRIANGLE

输入 #2复制

7 2 2 4

输出 #2复制

SEGMENT

输入 #3复制

3 5 9 1

输出 #3复制

IMPOSSIBLE

这是今天测试的题目。一眼看过去,略微思考一下,发现就是排序计算比较的题目。先把木棍按长度从小到大排序,那么只要第二根和第三根加起来长度大于第四根,那么就能形成一个三角形,输出TRIANGLE,如果第一根加上第二根等于第三根或第二根加上第三根等于第四根,那么就能形成一个退化三角形,输出SEGMENT,剩下的情况就是不可能组成三角形了,输出IMPOSSIBLE。

#include <bits/stdc++.h>

using namespace std;

void fast(int a[], int left, int right) //快速排序
{
	int t, L = left, R = right, m = a[left];
	if(L > R)
    	return;
	while(L < R)
	{
	    while(L < R && a[R] >= m) R --;
	    while(L < R && a[L] <= m) L ++;
	    if(L < R)
	    {
	        t = a[L], a[L] = a[R], a[R] = t;
	    }
	}
	a[left] = a[L];
	a[L] = m;
	fast(a, left, L - 1);
	fast(a, L + 1, right);
}

int main()
{
	int a[4];
	for(int i = 0;i < 4;i ++)
	{
		cin >> a[i];
	}
	fast(a, 0, 3);
	if(a[1] + a[2] > a[3]) cout << "TRIANGLE";
	else if(a[1] + a[2] == a[3] || a[0] + a[1] == a[2]) cout << "SEGMENT";
	else cout << "IMPOSSIBLE";
	return 0;
}


题目描述

Yakko, Wakko and Dot, world-famous animaniacs, decided to rest from acting in cartoons, and take a leave to travel a bit. Yakko dreamt to go to Pennsylvania, his Motherland and the Motherland of his ancestors. Wakko thought about Tasmania, its beaches, sun and sea. Dot chose Transylvania as the most mysterious and unpredictable place.

But to their great regret, the leave turned to be very short, so it will be enough to visit one of the three above named places. That's why Yakko, as the cleverest, came up with a truly genius idea: let each of the three roll an ordinary six-sided die, and the one with the highest amount of points will be the winner, and will take the other two to the place of his/her dreams.

Yakko thrown a die and got Y points, Wakko — W points. It was Dot's turn. But she didn't hurry. Dot wanted to know for sure what were her chances to visit Transylvania.

It is known that Yakko and Wakko are true gentlemen, that's why if they have the same amount of points with Dot, they will let Dot win.

输入格式

The only line of the input file contains two natural numbers Y and W — the results of Yakko's and Wakko's die rolls.

输出格式

Output the required probability in the form of irreducible fraction in format «A/B», where A — the numerator, and B — the denominator. If the required probability equals to zero, output «0/1». If the required probability equals to 1, output «1/1».

题意翻译

小Y,小W和小D进行扔骰子(六面)游戏,谁投出的点数最大算谁胜利,现在已知小Y和小W的得分,请你帮小D求出她获胜的概率

注意:

1.以"分子/分母"输出,特别的,若不可能获胜输出"0/1",100%获胜输出"1/1"

2.小Y和小W非常绅士,如果小D的得分和他们一样,他们也会算作小D获胜 Translated by @稀神探女

输入输出样例

输入 #1复制

4 2

输出 #1复制

1/2

说明/提示

Dot will go to Transylvania, if she is lucky to roll 4, 5 or 6 points.

一道签到题(?),赢的几率就是(6 - max(小Y的点数, 小W的点数) + 1) / 6,最后把分子分母化简一下就可以了。很简单。

#include <bits/stdc++.h>

using namespace std;

int main()
{
	int Y, W;
	cin >> Y >> W;
	int cc = max(Y, W);
	int chance = 6 - cc + 1;
//	cout << chance << endl;
	int k = 6;
	for(int m = 2;m <= 5;m ++)
	{
		while(chance % m == 0 && k % m == 0)
		{
			chance /= m;
			k /= m;
//			cout << m << endl;
//			cout << chance << "/" << k << endl;
		}
	}
	cout << chance << "/" << k;
	return 0;
}

很可惜,第3第4道题目死活做不出来,一道不知道哪里错了,一道溢出崩了不知道怎么改... ...


再加把劲!新题组也开了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ISansXI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值