B. Christmas Spruce
Consider a rooted tree. A rooted tree has one special vertex called the root. All edges are directed from the root. Vertex u is called a child of vertex v and vertex v is called a parent of vertex u if there exists a directed edge from v to u. A vertex is called a leaf if it doesn't have children and has a parent.
Let's call a rooted tree a spruce if its every non-leaf vertex has at least 3 leaf children. You are given a rooted tree, check whether it's a spruce.
The definition of a rooted tree can be found here.
The first line contains one integer n — the number of vertices in the tree (3 ≤ n ≤ 1 000). Each of the next n - 1 lines contains one integer pi (1 ≤ i ≤ n - 1) — the index of the parent of the i + 1-th vertex (1 ≤ pi ≤ i).
Vertex 1 is the root. It's guaranteed that the root has at least 2 children.
Print "Yes" if the tree is a spruce and "No" otherwise.
4 1 1 1
Yes
7 1 1 1 2 2 2
No
8 1 1 1 1 3 3 3
Yes
The first example:
The second example:
It is not a spruce, because the non-leaf vertex 1 has only 2 leaf children.
The third example:
题目大意:
给出树节点个数和每个节点的根,求这棵树是不是一颗云杉(每一个非叶子节点满足至少有三个叶子节点)。(没看到“至少”WA了一次)
思路:
构造这棵树然后进行宽搜遍历每一个节点看是否满足云杉条件。
代码:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1050;
vector<int >v[maxn];
queue<int> q;
int n;
int bfs()
{
int tag = 1;
q.push(1);
if(v[1].size() < 3) tag = 0;
while(q.size() && tag)
{
int t = q.front();
q.pop();
int cnt = 0;
for(int i = 0; i < v[t].size(); i++)
{
if(v[v[t][i]].size() == 0)
{
cnt++;
}
else if(v[v[t][i]].size() < 3)
{
tag = 0;
break;
}
else q.push(v[t][i]);
}
if(cnt < 3 && v[t].size() != 0) tag = 0;
}
return tag;
}
int main()
{
cin >> n;
for(int i = 2; i <= n; i++)
{
int t;
cin >> t;
v[t].push_back(i);
}
int flag = bfs();
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
C. Party Lemonade
A New Year party is not a New Year party without lemonade! As usual, you are expecting a lot of guests, and buying lemonade has already become a pleasant necessity.
Your favorite store sells lemonade in bottles of n different volumes at different costs. A single bottle of type i has volume 2i - 1 liters and costs ci roubles. The number of bottles of each type in the store can be considered infinite.
You want to buy at least L liters of lemonade. How many roubles do you have to spend?
The first line contains two integers n and L (1 ≤ n ≤ 30; 1 ≤ L ≤ 109) — the number of types of bottles in the store and the required amount of lemonade in liters, respectively.
The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 109) — the costs of bottles of different types.
Output a single integer — the smallest number of roubles you have to pay in order to buy at least L liters of lemonade.
4 12 20 30 70 90
150
4 3 10000 1000 100 10
10
4 3 10 100 1000 10000
30
5 787787787 123456789 234567890 345678901 456789012 987654321
44981600785557577
In the first example you should buy one 8-liter bottle for 90 roubles and two 2-liter bottles for 30 roubles each. In total you'll get 12 liters of lemonade for just 150 roubles.
In the second example, even though you need only 3 liters, it's cheaper to buy a single 8-liter bottle for 10 roubles.
In the third example it's best to buy three 1-liter bottles for 10 roubles each, getting three liters for 30 roubles.
题目大意:
给出柠檬水的种类数和节日需要的数量及各种类的价格。已知第i种柠檬水为2^(i-1) L,求最小花费。
思路:
因为相邻柠檬水重量有两倍关系,a[i]的最优解为min(a[i], a[i-1]*2),同时如果a[i+1] < a[i], a[i] = a[i+1];遍历一次保证每一个二进制位最优,然后进行二进制枚举。如果进制位为1,加上当前位,如果二进制位为0,则要比较当前花费和a[i+1]位花费哪个更小。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[32];
ll n, m, ans;
int main() {
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
a[i] = min(a[i], a[i-1] * 2);
a[i-1] = min(a[i], a[i-1]);
}
for(int i = n; i < 31; i++) a[i] = 2 * a[i-1];
for(int i = 0; i < 30; i++) {
if(m & (1 << i)) ans += a[i];
ans = min(ans, a[i+1]);
}
cout << ans << endl;
return 0;
}