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 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 1827
树形DP,U节点向子节点转移时,
ans′=ans–size∗w+(tot–size)∗w
ans′=ans+(tot–2∗size)∗w 若(tot–2∗size)<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 }