Solution
T1:首先可以想到分成两组暴搜+剪枝得到所有可能,然后meeting in middle,尴尬的是时间与空间,时间从2s—>5s—>12s(评测时才改的,考试时只到5s),对于时间12s可以直接快排,
226≈67000000
512M可以开两个刚刚好,考场上我以为快排过不了,就写了个基数排序,结果要开三个数组,空间炸了……标称方法是一边
224
记到数组,之后剩下的枚举也可以过,不过都是10s左右,对于空间上ljn大佬的方法是拿出4个来,剩下的
225
够开,剩下的4个
24
枚举即可,加上我的基数排序最慢的点2s也过了。
T2:
网上有题解:
http://blog.csdn.net/longyuepeng/article/details/38521877
http://blog.csdn.net/ypxrain/article/details/72864491
T3:类似POJ消防站一题,我在灰色的果实一题也写过,不过老师好像有另外的解法:f[i][j][k]表示i的水库距离为j,k表示是否在子树内。其实我也不会。
CODE
T1
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=34000000;
int a[100],b[100],c[2],cnt[1<<17];
int x[MAXN],y[MAXN],z[MAXN];
int cnta,cntb,cntx,cnty,W,n,ans=0;
void dfs1(int k,int sum)
{
if (sum>W) return;
if (k>cnta)
{
x[++cntx]=sum;
return;
}
dfs1(k+1,sum);
dfs1(k+1,sum+a[k]);
}
void dfs2(int k,int sum)
{
if (sum>W) return;
if (k>cntb)
{
y[++cnty]=sum;
return;
}
dfs2(k+1,sum);
dfs2(k+1,sum+b[k]);
}
void my_sort(int *x,const int &cntx)
{
//first;
memset(cnt,0,sizeof(cnt));
int bit=(1<<15)-1;
for (int i=1;i<=cntx;i++)
cnt[x[i]&bit]++;
for (int i=1;i<=bit;i++)
cnt[i]=cnt[i-1]+cnt[i];
for (int i=1;i<=cntx;i++)
z[cnt[x[i]&bit]]=x[i],cnt[x[i]&bit]--;
//second;
memset(cnt,0,sizeof(cnt));
for (int i=1;i<=cntx;i++)
cnt[z[i]>>15]++;
for (int i=1,p=1<<16;i<=p;i++)
cnt[i]=cnt[i-1]+cnt[i];
for (int i=cntx;i>=1;i--)
x[cnt[z[i]>>15]]=z[i],cnt[z[i]>>15]--;
}
void solve(int p)
{
int j=cnty;
for (int i=1;i<=cntx && j;i++)
{
while (j && x[i]+y[j]+p>W) j--;
if (j) ans=max(ans,x[i]+y[j]+p);
}
}
int main()
{
freopen("brick.in","r",stdin);
freopen("brick.out","w",stdout);
scanf("%d%d",&W,&n);
cnta=n/2-1; cntb=n-n/2-1;
for (int i=1;i<=cnta;i++)
scanf("%d",&a[i]);
for (int i=1;i<=cntb;i++)
scanf("%d",&b[i]);
scanf("%d%d",&c[0],&c[1]);
dfs1(1,0);
dfs2(1,0);
my_sort(x,cntx);
my_sort(y,cnty);
//sort(x+1,x+1+cntx);
//sort(y+1,y+1+cnty);
cntx=unique(x+1,x+1+cntx)-x-1;
cnty=unique(y+1,y+1+cnty)-y-1;
solve(0);
solve(c[0]);
solve(c[1]);
solve(c[0]+c[1]);
printf("%d\n",ans);
return 0;
}
T2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN=50050;
int n,Y,u;
int w[MAXN],v[MAXN],h[MAXN];
double ans;
struct node{
double t;
int id;
friend bool operator < (const node &x,const node &y)
{
return x.t>y.t;
}
};
priority_queue<node>Q;
inline double dis(int x,int y)
{return sqrt(x*x+y*y);}
int main()
{
freopen("river.in","r",stdin);
freopen("river.out","w",stdout);
scanf("%d%d%d",&n,&Y,&u);
for (int i=1;i<=n;i++)
scanf("%d",&w[i]);
for (int i=1;i<=n;i++)
scanf("%d",&v[i]);
for (int i=1;i<=n;i++)
ans+=w[i]/(double)v[i];
for (int i=1;i<=n;i++)
{
double dd=dis(1,w[i])-w[i];
Q.push((node){dd/v[i],i});
}
Q.push((node){1/(double)u,0});
for (int i=1;i<=Y;i++)
{
int id=Q.top().id;
ans+=Q.top().t;
if (!id) continue;
Q.pop();
h[id]++;
double dd=dis(h[id]+1,w[id])-dis(h[id],w[id]);
Q.push((node){dd/v[id],id});
}
printf("%.4f\n",ans);
return 0;
}
T3
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=1005;
int dis[MAXN][MAXN],dp[MAXN][MAXN],best[MAXN];
int c[MAXN],t[MAXN],Head[MAXN];
int n,tot=0,ans=0x3f3f3f3f;
struct Edge{
int v,next;
}edge[MAXN*2];
void add_edge(int x,int y)
{
edge[++tot]=(Edge){y,Head[x]};
Head[x]=tot;
}
void dfs_dis(int u,int pre,int rt)
{
for (int i=Head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if (v==pre) continue;
dis[rt][v]=dis[rt][u]+1;
dfs_dis(v,u,rt);
}
}
void dfs(int u,int pre)
{
for (int i=Head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if (v==pre) continue;
dfs(v,u);
}
for (int w=1;w<=n;w++)
{
dp[u][w]=c[w]+t[dis[w][u]];
for (int i=Head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if (v==pre) continue;
dp[u][w]+=min(dp[v][w]-c[w],best[v]);
}
best[u]=min(best[u],dp[u][w]);
}
}
int main()
{
freopen("reservoir.in","r",stdin);
freopen("reservoir.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&c[i]);
for (int i=1;i<=n;i++)
scanf("%d",&t[i]);
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y); add_edge(y,x);
}
for (int i=1;i<=n;i++) dfs_dis(i,0,i);
memset(dp,0x3f,sizeof(dp));
memset(best,0x3f,sizeof(best));
dfs(1,0);
cout<<best[1]<<endl;
return 0;
}