PJ 4 题解

T1.The Prices

首先数据范围:\(n\leqslant100,m\leqslant16\)
正解状压,一定要压\(m\)这一维
赛时想到状压但是不好表示于是打了基于当前状态的贪心拿了\(55pts\)
正解:
定义:\(dp[i][j]\) 表示前 \(i\) 个商店,买东西的状态为\(j\)时的最小花费。
首先枚举每个商家,然后加上路费。注意如果两次在同一条路上,需要减去重复的路费
然后枚举第\(i\)个商家的\(m\)件商品,并进行状态转移条件判断:想买第\(k\)件商品,则前\(i-1\)个商家没有买\(k\),所以\(j\)的二进制的第\(k\)\(0\)
然后状态转移方程就很简单:\(dp[i][j|(1<<k-1)]=min(dp[i][j|(1<<k-1)],dp[i][j]+a[i][k])\);
最后就不买第\(i\)个商家的物品和买第\(i\)个商家的物品的情况进行比较,选出最优解。

T2.上白泽慧音

Tarjan求强连通分量
赛时由于Tarjan忘干净了跑了
赛后想出一种做法就是:
Tarjan求出所有强连通分量然后用小根堆堆存一下
最后比大小的时候先比堆的\(size\)再比堆顶元素(字典序)
每个节点只属于一个SCC
所以对于每个存储SCC的堆来说堆顶不可能相同
从而比堆顶就可以得出更优的答案
记录下对应的SCC编号,直接去找对应堆的\(size\)并输出元素就行
本着不重复造能用的轮子的原则堆的实现直接std::priority_queue<int,vector<int>,greater<int> >就行了

T3 GCD&LCM

这个应该是“Hankson的趣味题”的弱化版
方便描述,记\(G=\)gcd(x,y),\(x_0=\frac{x}{G},y_0=\frac{y}{G},L\)lcm(x,y)
\(G*L=x*y\)
\(G*L=x_0*y_0*G^2\)
\(\frac{L}{G}=x_0*y_0\)
一切的前提是:
\(\frac{L}{G}\in N_+\)
于是得到一个特判:if(l%r)return;
非常好理解,和前提是等价的
然后就是第二个判断
\(\because G=\)gcd(x,y)
\(\therefore\)gcd(x0,y0)\(=1\)
不满足这个条件的,不合法
然后就可以有\(O(\frac{x}{y})\)的直接判断做法和\(O(\sqrt \frac{x}{y})\)分解因数做法
不过分解因数注意好处理,写法丑的就挂了

总结

T1贪心 T2 Tarjan板子不会 T3文件挂
反正挺弱的

posted @ 2022-05-28 17:45  2K22  阅读(57)  评论(0)    收藏  举报