Q - 生日蛋糕
分析:
- V、Q分别代表体积和表面积,在题目中,他们的值都带了π,所以我们可以将他们都看成整数就行了
- 求Q的时候,我们只需求侧面积以及最下层蛋糕的上底面的面积即可
设蛋糕从顶层到底层分别编号为1~m
- 从下往上搜索,这样的搜索方式可以减少搜索的分支(底层面积更大,半径更大)
- 搜索状态:当前层数u,u+1层的半径、高度h,m~u+1层的体积v和面积s
剪枝
- 上下界剪枝 枚举半径、高度
2.可行性剪枝(越界)
- 预处理每层的最小面积和体积:mins[ i ]、minv[ i ],如果当层面积或体积加上当层最小值大于总值,则剪去
3.最优性剪枝
- 当层最小侧面积和可用n-v来估价
- s + 2 * (n - v) / r >= ans
- for (int r_ = min(r - 1, (int)sqrt(n - v)); r_ >= u; r_--)
for (int h_ = min(h - 1, (n - v) / (r_ * r_)); h_ >= u; h_--)
DFS(u - 1, r_, h_, v + r_ * r_ * h_, s + 2 * r_ * h_ + (u == m ? r_ * r_ : 0));
代码:
#include<iostream> #include<cmath> using namespace std; const int N = 20, MA = 1e9; int m, n, ans = MA; int mins[N], minv[N]; void DFS(int u, int r, int h, int v, int s) { if (u == 0) { if (v == n) ans = min(ans, s); return; } if (v + minv[u] > n) return; if (s + mins[u] >= ans) return; if (s + 2 * (n - v) / r >= ans) return; for (int r_ = min(r - 1, (int)sqrt(n - v)); r_ >= u; r_--) for (int h_ = min(h - 1, (n - v) / (r_ * r_)); h_ >= u; h_--) DFS(u - 1, r_, h_, v + r_ * r_ * h_, s + 2 * r_ * h_ + (u == m ? r_ * r_ : 0)); } int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { minv[i] = minv[i - 1] + i * i * i; mins[i] = mins[i - 1] + 2 * i * i; } DFS(m, MA, MA, 0, 0); if (ans == MA) ans = 0; cout << ans << endl; return 0; }
Java
面向对象的简单训练
- 构建-类
- 标准的JavaBean类
- 类名需要见名知意
- 成员变量使用private修饰(保证安全)
- 提供之至少两个构造方法
无参构造方法
带全参的构造方法
4. 成员方法
提供每一个成员变量对应的set/get
或其他行为
package com.test1; import java.util.Random; public class Role { private String name; private int blood; public Role(String name, int blood) { this.name = name; this.blood = blood; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getBlood() { return blood; } public void setBlood(int blood) { this.blood = blood; } //定义攻击方向 public void sttack(Role role){ //计算造成伤害1~20 Random r = new Random(); int hurt = r.nextInt(20) + 1; //剩余血量 int reBlood = role.getBlood() - hurt; //对剩余血量判断 reBlood =reBlood < 0 ? 0 : reBlood; //修改挨打的血量 role.setBlood(reBlood); System.out.println(this.getName() + "打了"+role.getName() + "一下,造成了" + hurt + "的伤害," + role.getName() +"还剩" + reBlood + "血量"); } }
- 构建-对象
package com.test1; public class GameTest { public static void main(String[] args) { //1.创建第一个角色 Role r1 = new Role("小明" , 100); //2. Role r2 = new Role("小红" , 100); //3.开始,回合制 while(true){ //r1攻击r2 r1.sttack(r2); if(r2.getBlood() == 0) { System.out.println(r1.getName() + "KO了" + r2.getName()); break; } //r2攻击r1 r2.sttack(r1); if(r1.getBlood() == 0){ System.out.println(r2.getName() + "KO了" + r1.getName()); break; } } } }