USACO 刷水

Posted on 2016-09-05 21:42  yyjxx2010xyu  阅读(150)  评论(0编辑  收藏  举报

BZOJ 1666 水..

BZOJ 1579 分层图最短路.

BZOJ 1782 从一开始若某头牛停在U,那么U的子树的时间都会加一用BIT维护DFS序就行了

BZOJ 1572

贪心+堆 排序后查看是否超过了时间,超过了就弹出

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #define LL long long
 7 using namespace std;
 8 const LL Maxn=101000;
 9 struct Node{LL p,d;}A[Maxn];
10 LL Ans,Cnt,n;
11 priority_queue<LL> Q;
12 inline bool cmp(Node A,Node B)
13 {return A.d<B.d || (A.d==B.d && A.p<B.p);}
14 int main()
15 {
16     scanf("%lld",&n);
17     for (LL i=1;i<=n;i++) scanf("%lld%lld",&A[i].d,&A[i].p);
18      
19     sort(A+1,A+n+1,cmp); Cnt=0;
20     for (LL i=1;i<=n;i++)
21     {
22         Ans+=A[i].p; Cnt++; Q.push(-A[i].p);
23         if (Cnt>A[i].d) {Ans+=Q.top(); Q.pop(); Cnt--; }
24     }
25     printf("%lld\n",Ans);
26     return 0;
27 }
BZOJ 1572

BZOJ 1592

这道题有个结论就是最小花费的高度肯定和在原来的高度中.

这个结论感觉上非常显然,如果不在原来的高度中,那个肯定能从原来的高度中找到最优的.然后直接Dp就可以了

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxn=2010;
 7 const int Inf=0x3f3f3f3f;
 8 int a[Maxn],b[Maxn],C[Maxn][Maxn],F[Maxn][Maxn],Ans,n;
 9 inline int Min(int x,int y) {return x>y?y:x;}
10 inline int Abs(int x) {return x>0?x:-x;}
11 inline bool cmp1(int a,int b) {return a<b;}
12 inline bool cmp2(int a,int b) {return a>b;}
13 int main()
14 {
15     scanf("%d",&n);
16     for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
17     for (int i=1;i<=n;i++) F[i][0]=Inf;
18     sort(b+1,b+n+1,cmp1);
19     for (int i=1;i<=n;i++)
20         for (int j=1;j<=n;j++)
21         {
22             C[i][j]=F[i-1][j]+Abs(b[j]-a[i]);
23             F[i][j]=Min(F[i][j-1],C[i][j]);
24         }
25     Ans=F[n][n];
26     sort(b+1,b+n+1,cmp2);
27     for (int i=1;i<=n;i++)
28         for (int j=1;j<=n;j++)
29         {
30             C[i][j]=F[i-1][j]+Abs(b[j]-a[i]);
31             F[i][j]=Min(F[i][j-1],C[i][j]);
32         }
33     printf("%d\n",Min(Ans,F[n][n]));
34     return 0;
35 }
BZOJ 1592

 BZOJ 1827

树形DP,U节点向子节点转移时,

ans=anssizew+(totsize)w

ans=ans+(tot2size)若(tot2size)<0那么ans'比ans优

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #define LL long long
 6 using namespace std;
 7  
 8 const LL Maxn=100500;
 9 struct EDGE{LL to,next,w;}edge[Maxn<<1];
10 LL head[Maxn],C[Maxn],n,u,v,w,Ans,Dis[Maxn],Size[Maxn],cnt;
11 inline void Add(LL u,LL v,LL w)
12 {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
13 LL Dfs(LL u,LL fa)
14 {
15     LL Ret=Dis[u]*C[u]; Size[u]=C[u];
16     for (LL i=head[u];i!=-1;i=edge[i].next)
17     {
18         if (edge[i].to==fa) continue;
19         Dis[edge[i].to]=Dis[u]+edge[i].w;
20         Ret+=Dfs(edge[i].to,u);
21         Size[u]+=Size[edge[i].to];
22     }
23     return Ret;
24 }
25 void Move(LL u,LL fa)
26 {
27     for (LL i=head[u];i!=-1;i=edge[i].next)
28     {
29         if (edge[i].to==fa) continue;
30         if (Size[1]-2*Size[edge[i].to]<0)
31         {
32             Ans+=(Size[1]-2*Size[edge[i].to])*edge[i].w;
33             Move(edge[i].to,u);
34         }
35     }
36 }
37 int main()
38 {
39     scanf("%lld",&n);
40     for (LL i=1;i<=n;i++) scanf("%lld",&C[i]);
41     memset(head,-1,sizeof(head));
42     for (LL i=1;i<n;i++) 
43     {
44         scanf("%lld%lld%lld",&u,&v,&w);
45         Add(u,v,w),Add(v,u,w);
46     }
47     Ans=Dfs(1,0);
48     Move(1,0);
49     printf("%lld\n",Ans);
50     return 0;
51 }
BZOJ 1827