220510总结
220510总结
从此加入快读大军乐
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
return x*f;
}
T1 对抗赛
首先考虑在什么情况下无解
显然是没法平均分的情况下
因此,如果这些奖品的总价值 \(\text{sum}\) 为奇数,可以直接输出 \(0\)
接下来就是找凑成 \(\dfrac{\text{sum}}{2}\) 的方案数了
设 \(f(i)\) 表示凑成 \(i\) 的方案数,\(A_j\) 表示物品 \(j\) 的价值,注意逆序枚举
那么状态转移方程为 \(f(i) = \displaystyle \sum^{j\leq\text{sum}/2}_{j=A_j}f(i-A_j)\)
初始状态:\(f(0)=1\)
dp[0] = 1;
for(int i = 1;i<=N;i++){
for(int j = HS;j>=A[i];j--){
dp[j] += dp[j - A[i]];
}
}
printf("%d",dp[HS]>>1);
T2 热浪
直接套 \(\operatorname{Dijkstra}\) 板子就行
T3 演讲大厅安排
挺像贪心的dp
之前好像做过类似的题但我找不到了(
首先按照结束时间排序
然后对于每个事件,找出在它之前最多可以进行总演讲时长
然后加上本场演讲的时长
sort(event+1,event+N+1);
for(int i = 1;i<=N;i++){
for(int j = 1;j<i;j++){
if(event[i].st >= event[j].ed) dp[i] = max(dp[i],dp[j]);
}
dp[i] += event[i].len;
}
T4 分糖果
被极限数据卡自闭了
十万个小朋友是什么概念
其实也是 \(\operatorname{Dijkstra}\) 板子题
但是数据有点过分
用了快读、堆优化 \(\operatorname{Dijkstra}\) 、邻接表存图才卡着时限过的点
(我也不知道为什么邻接表能过链式前向星过不了
#include<bits/stdc++.h>
using namespace std;
#define FO(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout)
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
return x*f;
}
const int maxN = (1e5+10);
vector<int>edge[maxN];
int dis[maxN];
int vis[maxN];
int ans;
struct Node{
int dis,pos;
friend bool operator < (Node A,Node B){
return A.dis > B.dis;
}
};
inline void Dijkstra(int s){
memset(dis,0x7f,sizeof(dis));
priority_queue<Node> Q;
dis[s] = 1;
vis[s] = 1;
Q.push((Node){1,s});
while(!Q.empty()){
int u = Q.top().pos;
Q.pop();
for(register int i = 0;i<edge[u].size();i++){
int v = edge[u][i];
if(dis[v] > dis[u] + 1){
dis[v] = 1 + dis[u];
if(!vis[v]){
Q.push((Node){dis[v],v});
vis[v] = 1;
ans = max(ans,dis[v]);
}
}
}
}
}
int N,P,C;
int M;
int main(){
FO("candy");
N=read(),P=read(),C=read(),M=read();
for(register int i = 1;i<=P;i++){
int a,b;
a = read();
b = read();
edge[a].push_back(b);
edge[b].push_back(a);
}
Dijkstra(C);
printf("%d\n",ans+M);
return 0;
}