刷usaco水题的一些启示
就是断断续续刷了一些银组的题,虽说真的有点水,因为这些题大多是简单转化一下模型就可以了,但还是有一些启示吧
bzoj1618
完全背包的方程要理解好
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxh=50005; 6 const int maxn=105; 7 const int inf=3e8; 8 int weight[maxn]; 9 int cost[maxn]; 10 int n,h; 11 int f[maxh+5000]; 12 int main(){ 13 scanf("%d%d",&n,&h); 14 for (int i=1;i<=n;i++) 15 scanf("%d%d",&weight[i],&cost[i]); 16 memset(f,127/3,sizeof(f)); 17 f[0]=0; 18 for (int i=1;i<=n;i++){ 19 for (int j=weight[i];j<=h+5000;j++) 20 f[j]=min(f[j],f[j-weight[i]]+cost[i]); 21 }//理解清楚方程...一次加一件直到无法取为止 22 int ans=inf; 23 for (int i=h;i<=h+5000;i++) 24 ans=min(ans,f[i]); 25 printf("%d\n",ans); 26 return 0; 27 }
bzoj1623
要简单分析一下奶牛车速大小与顺序前后的关系
重点在于看出把速度较小的奶牛放在前面会使答案尽可能大,贪心地排个序即可
bzoj1619
有时候会因为简化了不同程度上问题的样例而忽略了某些需要在代码中注意的点
灌水要从最高点开始
bzoj1635
这题有点意思。显然我们可以用维护差分序列的思想去做这道题。一开始没细想直接wa了两发,实际上有很多细节还是值得体味的
1.可以知道区间是不会重合的,顶多端点重合
2.知道第1条的作用就是,我们可以抛掉h[b]>=h[a]这个条件,因为一开始del[a]=del[b]=0,而区间又是不重合的
3.需要判重!!因为区间虽然不能重合但是它可以重复啊!!
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxn=10200; 7 const int maxh=1000100; 8 struct L{ 9 int l,r; 10 }num[maxn]; 11 int del[maxn];//差分序列 12 int n,m,H,I,a,b; 13 bool cmp(L a,L b){ 14 return (a.l<b.l||(a.l==b.l&&a.r<b.r)); 15 } 16 int main(){ 17 scanf("%d%d%d%d",&n,&I,&H,&m); 18 for (int i=1;i<=m;i++){ 19 scanf("%d%d",&num[i].l,&num[i].r); 20 if (num[i].l>num[i].r) swap(num[i].l,num[i].r); 21 } 22 sort(num+1,num+1+m,cmp); 23 for (int i=1;i<=m;i++) 24 if (i==1||num[i].l!=num[i-1].l||num[i].r!=num[i-1].r){ 25 del[num[i].l+1]--,del[num[i].r]++; 26 } 27 for (int i=1;i<=n;i++) 28 del[i]=del[i-1]+del[i]; 29 int t=H-del[I]; 30 for (int i=1;i<=n;i++) 31 printf("%d\n",del[i]+t); 32 return 0; 33 }