今天上午考试
下午就放假了
自己都没想到,就虐场了
\(T0\) 产品排序
J哥说是送分题,然而我们并不这么觉得,毕竟只有2个人A了
。。我的玄学搜索+贪心优化+卡时直接A了,速度还比正解\(DP\)(Zgx)快了很多倍?
试想,若一个机器加工的产品是确定好的,那么显然把冷却时间长的放在前面加工要更优,所以我们把所有产品按冷却时间降序排序,然后依次放,这样就省去了统计答案的时间。
于是开始搜索,每个产品有两个选择:
1、让\(1\)机器加工
2、让\(2\)机器加工
直接搜时间复杂度是\(O(2^n)\),而\(n\)最大是\(200\),显然过不了。所以考虑优化。
1、最优性剪枝
2、贪心优化搜索顺序
3、卡时
void dfs(int now, int sum1, int sum2, int p1, int p2){ //sum1是机器1的加工时间,p1是机器1的总时间,sum2、p2同理
if(max(p1, p2) >= ans) return; //最优性剪枝
if(now == n + 1){ ans = max(p1, p2); return; }
if(++Time >= 150000) printf("%d\n", ans), exit(0); //无敌的卡时,如果你问为什么15W就停?因为我怕爆栈
if(p1 < p2){ //贪心优化搜索顺序,优先往当前时间少的机器放,尽量让2个机器平均
dfs(now + 1, sum1 + s[now].a, sum2, max(p1, sum1 + s[now].a + s[now].b), p2); //放在机器1
dfs(now + 1, sum1, sum2 + s[now].a, p1, max(p2, sum2 + s[now].a + s[now].b)); //放在机器2
}
else{
dfs(now + 1, sum1, sum2 + s[now].a, p1, max(p2, sum2 + s[now].a + s[now].b));
dfs(now + 1, sum1 + s[now].a, sum2, max(p1, sum1 + s[now].a + s[now].b), p2);
}
}
为什么这么卡时能得到正确答案?
我们贪心优化了搜索顺序,使得每次搜到的都是一个比较优的解,所以那些不优的会被直接剪枝剪掉,15W次足够我们搜到很多优解,最优解也就有极大可能在其中。
神不神奇?
\(T1\) 倒水
思维难度不大。
类似与2048的东西,容易想到二进制,\(n\)的二进制位上有多少个\(1\)就说明最后至少合并成多少个瓶子,我们就是要对\(n\)加上一个数,使得\(n\)的二进制位上只有至多\(k\)个1。
贪心乱搞就好了。伪代码如下
while(1的个数>k){
找到进位所需的数最小的1,使之进位,并统计答案
}
while(xbq_is_shouting){
if(sum <= k) break;
now = 0; Min = 2147483647; sum = 0;
for(int i = 0; i < w; ++i)
if(n & (1 << i)){
++sum;
if((1 << i) - now < Min)
Min = (1 << i) - now;
now &= (1 << i);
}
n += Min; ans += Min;
}
\(T2\) 单词缩写
正解不会啊
写了搜索居然搜了\(80'\)
\(T3\) 求和
不可做题。。高精减除乘都有。。哎算了\(还是拿暴力分吧\)
\(T4\) 象棋比赛
贪心水题嘛。
先按实力排序一遍,再把实力相邻的两个人的差再升序排序一遍,然后顺着取就好了。显然是最优的。
于是390'虐场
其实我只是把该拿的分拿了,稳点就行了。
\(9.25\)计划:
改题,写《软件安装》《矿场搭建》