(寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題)
阿新 • • 發佈:2019-03-18
ogr sign n) you end max ext %d col
layout: post
title: (寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題)
author: "luowentaoaa"
catalog: true
tags:
mathjax: true
- codeforces
- DP
- 狀態壓縮
- LCA
傳送門
付隊!
C - Greetings! (狀態壓縮)
題意
給N種信件,你可以任意選擇K種信封裝信件,問你最少的浪費是多少
不能大的信件裝進小信封中
思路
首先如果可以選擇的信封數量比N大 那麽每一種信件用一個特定的信封肯定不會有浪費
因為數據很小我們考慮狀態壓縮考慮哪些信件用同一種信封
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const ll mod=1e9+7; const int maxn=(1<<16)+50; const int inf=1e8; ll c[maxn]; struct node{ ll w,h,t; }my[20]; ll dp[20][maxn]; int main() { int n,k; cin>>n>>k; memset(dp,127,sizeof(dp)); for(int i=0;i<n;i++)cin>>my[i].w>>my[i].h>>my[i].t; for(int i=0;i<(1<<n);i++){ ll ww=0,hh=0,sum=0,cnt=0; for(int j=0;j<n;j++){ if(i&(1<<j)){ sum+=my[j].w*my[j].h*my[j].t; ww=max(ww,my[j].w); hh=max(hh,my[j].h); cnt+=my[j].t; } } dp[1][i]=c[i]=(ww*hh*cnt-sum); } for(int i=2;i<=k;i++){ dp[i][0]=0; for(int sta=0;sta<(1<<n);sta++){ for(int t=sta;t;t=(t-1)&sta){ dp[i][sta]=min(dp[i][sta],dp[i-1][t]+c[sta^t]); } } } cout<<dp[k][(1<<n)-1]; return 0; }
F - Mountain Scenes (DP)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const ll mod=1e9+7; const int maxn=5e5+50; const int inf=1e8; ll dp[150][25000]; int main() { int n,w,h; cin>>n>>w>>h; dp[0][0]=1; for(int i=1;i<=w;i++){ for(int j=0;j<=n;j++){ for(int k=0;k<=h;k++){ dp[i][j+k]+=dp[i-1][j]; dp[i][j+k]%=mod; } } } ll ans=0; for(int i=0;i<=n;i++){ ans+=dp[w][i]; ans%=mod; } if(w*h<=n)ans=(ans-h+mod-1)%mod; else ans=(ans-n/w+mod-1)%mod; cout<<ans<<endl; return 0; }
I - Tourists (LCA)
思路
很像wls面試我時出的題目
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll mod=1e9+7;
const int maxn=2e5+50;
const int inf=1e8;
int Next[maxn<<1],To[maxn<<1],Laxt[maxn<<1];
int cnt;
void add(int u,int v){
Next[++cnt]=Laxt[u];Laxt[u]=cnt;To[cnt]=v;
}
int n;
int fa[maxn][50],dep[maxn];
void dfs(int u,int faa){
fa[u][0]=faa;
dep[u]=dep[faa]+1;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]==faa)continue;
dfs(To[i],u);
}
}
void init(){
for(int i=1;i<=20;i++){
for(int j=1;j<=n;j++){
int f=fa[j][i-1];
fa[j][i]=fa[f][i-1];
}
}
}
int lca(int p,int q){
if(dep[p]<dep[q])swap(p,q);
for(int i=20;i>=0;i--){
if(dep[fa[p][i]]>=dep[q])p=fa[p][i];
}
if(p==q)return q;
for(int i=20;i>=0;i--){
if(fa[p][i]!=fa[q][i]){
p=fa[p][i];q=fa[q][i];
}
}
return fa[p][0];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0);
ll ans=0;
init();
for(int i=1;i<=n;i++){
for(int j=2*i;j<=n;j+=i){
int f=lca(i,j);
ans+=dep[i]+dep[j]-2*dep[f]+1;
}
}
printf("%lld\n",ans);
return 0;
}
(寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題)