EXAM個人訓練賽四
阿新 • • 發佈:2018-07-29
還要 無向圖 結構性 為我 efi 括號 reat 第一次用 cos
EXAM個人訓練賽四
已完成
- [x] A
- [x] D
- [x] E
- [x] F
- [x] J
- [x] K
- [x] I*
未完成
- [x] B
- [x] C
- [x] G
- [x] H
簽到水題 A J F
A:英文字母有2426個
J:註意long long
D:Transit Tree Path
我直接套了單源最短路的一個模板,有人用的是DFS,模板第一次用,記得是無向圖。
代碼又臭又長:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; const long long INF=1e17; long long dist[maxn]; #define ll long long bool vis[maxn]; struct node { int v,c; node(int _v=0,int _c=0):v(_v),c(_c){} bool operator <(const node &r) const { return c>r.c; } }; struct edge { ll v,cost; edge(ll _v=0,ll _cost=0):v(_v),cost(_cost){} }; vector<edge>str[maxn]; void dijk(int n,int start) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) dist[i]=INF; priority_queue<node>q; while(!q.empty()) { q.pop(); } dist[start]=0; q.push(node(start,0)); node tmp; while(!q.empty()) { tmp=q.top(); q.pop(); int u=tmp.v; if(vis[u]) continue; vis[u]=true; for(int i=0;i<str[u].size();i++){ int v=str[tmp.v][i].v; ll cost=str[u][i].cost; if(!vis[v]&&dist[v]>dist[u]+cost) { dist[v]=dist[u]+cost; q.push(node(v,dist[v])); } } } } void add(int u,int v,int w) { str[u].push_back(edge(v,w)); } int main() { int n; scanf("%d",&n); int a,b,c; for(int i=0;i<n-1;i++){ scanf("%d%d%d",&a,&b,&c); add(b,a,c); add(a,b,c); } int k,q; scanf("%d%d",&k,&q); dijk(n,q); for(int i=1;i<=k;i++){ scanf("%d%d",&a,&b); printf("%lld\n",dist[a]+dist[b]); } return 0; }
E Lemonade Line
完全是英語閱讀理解,題目讀不懂,看樣例也很難看懂,其實代碼很簡單。
K 打地鼠遊戲
單調隊列,剛開始想復雜了,只要隊列中有數比要插進來的數小就替換最小的
priority_queue<int, vector<int>, greater<int>>Q;
I 經營與開發
看了題解說什麽正難則反一大堆,根本看不懂
終於找到一個有說服力的:
這個我對樓下做出點補充,記最終答案為ans,其實對於每個星球不管是維修還是資源型,都可以把對鉆頭的改變度記作一個常數k,而且k是有後效性的。我們先具一個i=4的例子,ans=wk1a1+wk1
k2a2+wk1k2k3a3+wk1k2k3k4a4,即ans=w(k1a1+k1k2a2+k1k2k3a3+k1k2k3a4),進一步提公因式就是ans=w(k1(a[1]+k2(a[2]+k3(a[3]+k4a[4]))))(這叫什麽數學名詞來著,蒟蒻忘了),實際上對於每個a[i],a[i]前還要乘上一個符號變量t(維修+1,資源-1,不選乘0)。即ans=w(k1(t1a[1]+k2(t2a[2]+k3(t3a[3]+k4t4a[4]))))那麽我們的題目就變為對每項選擇最優的符號變量得出最大的答案值。照樓下的思路我們是要從最裏面的括號開始推,確保每次括號裏的值都最大。
這是因為我們要求的總問題就是使的w(內的值最大)。而每個階段的決策是tia[i]+ki*(內的值)。因為後一項肯定為正,由最優子結構性質得(內的值一定是最大值)。這樣以來樓下的思路就通了。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100010;
int n,w,i[maxn],h[maxn];
double k,c,ans;
int main()
{
scanf("%d%lf%lf%d",&n,&k,&c,&w);
k=1-0.01*k;
c=1+0.01*c;
for (int a=1;a<=n;a++)
scanf("%d%d",&i[a],&h[a]);
for (int a=n;a;a--)
if (i[a]==1)
ans=max(ans,ans*k+h[a]);
else
ans=max(ans,ans*c-h[a]);
printf("%.2lf\n",ans*w);
return 0;
}
EXAM個人訓練賽四