1. 程式人生 > >刷usaco水題的一些啟示

刷usaco水題的一些啟示

pen close ron 奶牛 code 問題 can ans col

就是斷斷續續刷了一些銀組的題,雖說真的有點水,因為這些題大多是簡單轉化一下模型就可以了,但還是有一些啟示吧

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 }
View Code

刷usaco水題的一些啟示