期末考试结束又到了做题的时候了

hdu5964

大胆推出公式,发现面积可以转换为两个互相独立的参数函数……

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 ll a,b,c,d;
 6 ll mi,mx,x,y;
 7 int main()
 8 {
 9     int n;
10     while (scanf("%lld%lld%lld%lld",&a,&b,&c,&d)!=EOF)
11     {
12         scanf("%d",&n);
13         mi=1e20; mx=0;
14         for (int i=0; i<n; i++)
15         {
16             scanf("%lld%lld",&x,&y);
17             mi=min(mi,a*c*x*x+b*d*y*y+(a*d+b*c)*x*y);
18             mx=max(mx,a*c*x*x+b*d*y*y+(a*d+b*c)*x*y);
19         }
20         printf("%lld\n",(ll)(fabs(1.0*(mx-mi)/(a*d-b*c))+0.5));
21     }
22     return 0;
23 }
View Code

 

hdu3457 3458

双倍经验,先把矩形分成左下右上两个点然后一维排序,一维树状数组维护;处理时矩形两个点,一个点查询,一个点更新

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 struct node{int x,y,id;} a[200010];
 5 int b[200010],c[200010],op[200010],wh[200010],f[200010];
 6 int n;
 7 
 8 void add(int x,int w)
 9 {
10     for (int i=x; i<=2*n; i+=i&(-i))
11       b[i]=max(b[i],w);
12 }
13 
14 int ask(int x)
15 {
16     int s=0;
17     for (int i=x; i; i-=i&(-i))
18       s=max(b[i],s);
19     return s;
20 }
21 bool cmp(node a,node b)
22 {
23     if (a.x==b.x&&a.y==b.y) return a.id<b.id;
24     if (a.x==b.x) return a.y<b.y;
25     return a.x<b.x;
26 }
27 
28 int main()
29 {
30   //  freopen("1.in","r",stdin);
31     scanf("%d",&n);
32     while (n)
33     {
34         for (int i=1; i<=n; i++)
35         {
36             scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i+n].x,&a[i+n].y);
37             a[i].id=i;
38             a[i+n].id=i+n;
39             b[i]=a[i].y; b[i+n]=a[i+n].y;
40         }
41         sort(a+1,a+1+2*n,cmp);
42         sort(b+1,b+1+2*n);
43         int m=1; c[1]=b[1];
44         for (int i=2; i<=2*n; i++) if (b[i]!=b[i-1]) c[++m]=b[i];
45         for (int i=1; i<=2*n; i++)
46         {
47             a[i].y=lower_bound(c+1,c+1+m,a[i].y)-c;
48             if (a[i].id<=n) op[a[i].id]=i;
49         }
50         for (int i=1; i<=2*n; i++)
51             if (a[i].id>n) wh[i]=op[a[i].id-n];
52         memset(b,0,sizeof(b));
53         int ans=0;
54         for (int i=1; i<=2*n; i++)
55         {
56             if (a[i].id<=n)
57             {
58                 f[i]=ask(a[i].y-1)+1;
59                 ans=max(ans,f[i]);
60             }
61             else add(a[i].y,f[wh[i]]);
62         }
63         printf("%d\n",ans);
64         scanf("%d",&n);
65     }
66 }
View Code

 

hdu1964

插头dp的模板题练练手

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 typedef long long ll;
  5 const int mo=30007;
  6 const int maxl=1000010;
  7 int r[15][15],d[15][15],b[15],v[15],n,m,p;
  8 string s;
  9 
 10 struct node{
 11     int p[mo],f[maxl],len,nex[maxl];
 12     ll st[maxl];
 13     void clr()
 14     {
 15         len=0;
 16         memset(p,255,sizeof(p));
 17     }
 18     void push(ll nw,int s)
 19     {
 20         int x=nw%mo;
 21         for (int i=p[x]; i>-1; i=nex[i])
 22             if (st[i]==nw)
 23             {
 24                 f[i]=min(f[i],s);
 25                 return;
 26             }
 27         st[++len]=nw; f[len]=s;
 28         nex[len]=p[x]; p[x]=len;
 29     }
 30 } h[2];
 31 
 32 void get(ll st)
 33 {
 34     for (int i=m; i>=0; i--)
 35     {
 36         b[i]=st&7;
 37         st>>=3;
 38     }
 39 }
 40 
 41 ll put()
 42 {
 43     memset(v,255,sizeof(v)); v[0]=0;
 44     ll st=0; int t=0;
 45     for (int i=0; i<=m; i++)
 46     {
 47         if (v[b[i]]==-1) v[b[i]]=++t;
 48         b[i]=v[b[i]];
 49         st<<=3; st|=b[i];
 50     }
 51     return st;
 52 }
 53 
 54 void shift()
 55 {
 56     for (int i=m; i; i--) b[i]=b[i-1];
 57     b[0]=0;
 58 }
 59 
 60 void work(int j,int s)
 61 {
 62     if (j==m) shift();
 63     h[p].push(put(),s);
 64 }
 65 
 66 void dp(int i,int j)
 67 {
 68     for (int k=1; k<=h[p^1].len; k++)
 69     {
 70         get(h[p^1].st[k]);
 71         int x=b[j],y=b[j-1],s=h[p^1].f[k];
 72         if (x&&y)
 73         {
 74             if ((x!=y)||(x==y&&i==n&&j==m))
 75             {
 76                 b[j]=b[j-1]=0;
 77                 if (x!=y)
 78                     for (int z=0; z<=m; z++)
 79                         if (b[z]==x) b[z]=y;
 80                 work(j,s);
 81             }
 82         }
 83         else if ((x&&!y)||(!x&&y))
 84         {
 85             int z=x+y;
 86             if (j<m)
 87             {
 88                 b[j]=z; b[j-1]=0;
 89                 work(j,s+r[i][j]);
 90             }
 91             if (i<n)
 92             {
 93                 b[j]=0; b[j-1]=z;
 94                 work(j,s+d[i][j]);
 95             }
 96         }
 97         else if (i<n&&j<m)
 98         {
 99             b[j]=b[j-1]=m+1;
100             work(j,s+d[i][j]+r[i][j]);
101         }
102     }
103 }
104 
105 int main()
106 {
107     int cas;
108     scanf("%d",&cas);
109     while (cas--)
110     {
111         scanf("%d%d\n",&n,&m);
112         memset(r,255,sizeof(r));
113         memset(d,255,sizeof(d));
114         for (int i=1; i<=2*n+1; i++)
115         {
116             getline(cin,s);
117             for (int j=1; j<=2*m; j++)
118                 if (s[j]>='0'&&s[j]<='9')
119                 {
120                     if (i&1) d[i/2][(j+1)/2]=s[j]-'0';
121                     else r[i/2][(j+1)/2]=s[j]-'0';
122                 }
123         }
124         h[0].clr();
125         h[0].push(0,0);
126         p=0;
127         for (int i=1; i<=n; i++)
128             for (int j=1; j<=m; j++)
129             {
130                // printf("%d %d\n",r[i][j],d[i][j]);
131                 p^=1; h[p].clr();
132                 dp(i,j);
133             }
134         printf("%d\n",h[p].f[1]);
135     }
136 }
View Code

 

hdu5730

设f[i][j][s1][s2]表示到第i个和为j用了s1个必选,s2个必不选,每个数有必选、必不选、选、不选4种情况

注意这道题卡时

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int mo=1000000007;
 5 int f[1005][1005][3][3],a[1010],n,s;
 6 void inc(int &a,int b)
 7 {
 8     a+=b;
 9     if (a>=mo) a-=mo;
10 }
11 
12 int main()
13 {
14     int cas;
15     scanf("%d",&cas);
16     while (cas--)
17     {
18         scanf("%d%d",&n,&s);
19         memset(f,0,sizeof(f));
20         for (int i=1; i<=n; i++) scanf("%d",&a[i]);
21         f[0][0][0][0]=1;
22         for (int i=1; i<=n; i++)
23         {
24             for (int j=0; j<=s; j++)
25                 for (int s1=0; s1<=2; s1++)
26                     for (int s2=0; s2<=2; s2++)
27                     {
28                         if (j+a[i]<=s)
29                         {
30                             inc(f[i][j+a[i]][s1][s2],f[i-1][j][s1][s2]);
31                             if (s1<2) inc(f[i][j+a[i]][s1+1][s2],f[i-1][j][s1][s2]);
32                         }
33                         inc(f[i][j][s1][s2],f[i-1][j][s1][s2]);
34                         if (s2<2) inc(f[i][j][s1][s2+1],f[i-1][j][s1][s2]);
35                     }
36         }
37         int ans=0;
38         for (int i=0; i<=s; i++) inc(ans,f[n][i][2][2]);
39         printf("%lld\n",4ll*ans%mo);
40     }
41 }
View Code

 

poj2699

如果有k个strong king,那么可以构造出分数k大为strong king的方案,于是枚举strong king个数经典的建图最大流判断之

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 
  8 struct way{int next,flow,po;} e[200010];
  9 int numh[110],h[110],cur[110],pre[110],a[110],p[110],t,n,len;
 10 string s;
 11 
 12 void add(int x,int y,int f)
 13 {
 14     e[++len].po=y;
 15     e[len].flow=f;
 16     e[len].next=p[x];
 17     p[x]=len;
 18 }
 19 
 20 void build(int x,int y,int f)
 21 {
 22     add(x,y,f);
 23     add(y,x,0);
 24 }
 25 
 26 int sap()
 27 {
 28     for (int i=0; i<=t; i++)
 29     {
 30         cur[i]=p[i];
 31         h[i]=numh[i]=0;
 32     }
 33     numh[0]=t+1;
 34     int u=0,s=0;
 35     while (h[0]<t+1)
 36     {
 37         bool ff=1;
 38         for (int i=cur[u]; i>-1; i=e[i].next)
 39         {
 40             int j=e[i].po;
 41             if (e[i].flow&&h[u]==h[j]+1)
 42             {
 43                 pre[j]=u; cur[u]=i; u=j;
 44                 ff=0;
 45                 if (u==t)
 46                 {
 47                     s++;
 48                     if (s==(n-1)*n/2) return s;
 49                     while (u)
 50                     {
 51                         u=pre[u];
 52                         j=cur[u];
 53                         e[j].flow--; e[j^1].flow++;
 54                     }
 55                 }
 56                 break;
 57             }
 58         }
 59         if (ff)
 60         {
 61             if (--numh[h[u]]==0) return s;
 62             int q=-1,tmp=t;
 63             for (int i=p[u]; i>-1; i=e[i].next)
 64             {
 65                 int j=e[i].po;
 66                 if (e[i].flow&&h[j]<tmp)
 67                 {
 68                     tmp=h[j];
 69                     q=i;
 70                 }
 71             }
 72             h[u]=tmp+1; numh[h[u]]++; cur[u]=q;
 73             if (u) u=pre[u];
 74         }
 75     }
 76     return s;
 77 }
 78 
 79 bool check(int k)
 80 {
 81     len=-1; memset(p,255,sizeof(p));
 82     for (int i=1; i<=n; i++)
 83         build(0,i,a[i]);
 84     int w=n;
 85     for (int i=1; i<n; i++)
 86         for (int j=i+1; j<=n; j++)
 87         {
 88             build(++w,t,1);
 89             build(i,w,1);
 90             if (!(i>n-k&&a[j]>a[i])) build(j,w,1);
 91         }
 92     if (sap()==n*(n-1)/2) return 1; else return 0;
 93 }
 94 
 95 int main()
 96 {
 97     int cas;
 98     scanf("%d\n",&cas);
 99     while (cas--)
100     {
101         getline(cin,s);
102         int l=s.length();
103         int i=0; n=0;
104         while (i<l)
105         {
106             int x=0,j=i;
107             for (; j<l&&s[j]!=' '; j++) x=x*10+s[j]-'0';
108             if (s[i]>= '0'&&s[i]<= '9') a[++n]=x;
109             i=j+1;
110         }
111         t=n*(n-1)/2+n+1;
112         int ans=1;
113         for (int i=n; i; i--)
114             if (check(i))
115             {
116                 ans=i;
117                 break;
118             }
119         printf("%d\n",ans);
120     }
121 }
View Code

 

spoj287

经典的二分颜色数+最大流判定

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 
  7 using namespace std;
  8 const int inf=100000007;
  9 struct way{int po,next,flow;} e[800010];
 10 vector<int> g[510];
 11 int len,n,m,k,t,pre[510],numh[510],cur[510],h[510],d[510],p[510],a[510];
 12 
 13 void add(int x,int y,int f)
 14 {
 15      e[++len].po=y;
 16      e[len].flow=f;
 17      e[len].next=p[x];
 18      p[x]=len;
 19 }
 20 
 21 void build(int x, int y, int f)
 22 {
 23      add(x,y,f);
 24      add(y,x,0);
 25 }
 26 
 27 int sap()
 28 {
 29     memset(h,0,sizeof(h));
 30     memset(numh,0,sizeof(numh));
 31     numh[0]=t+1;
 32     for (int i=0; i<=t; i++) cur[i]=p[i];
 33     int j,u=0,s=0,neck=inf;
 34     while (h[0]<t+1)
 35     {
 36           d[u]=neck;
 37           bool ch=1;
 38           for (int i=cur[u]; i!=-1; i=e[i].next)
 39           {
 40               j=e[i].po;
 41               if (e[i].flow>0&&h[u]==h[j]+1)
 42               {
 43                  neck=min(neck,e[i].flow);
 44                  cur[u]=i;
 45                  pre[j]=u;  u=j;
 46                  if (u==t)
 47                  {
 48                     s+=neck;
 49                     while (u)
 50                     {
 51                           u=pre[u];
 52                           j=cur[u];
 53                           e[j].flow-=neck;
 54                           e[j^1].flow+=neck;
 55                     }
 56                     neck=inf;
 57                  }
 58                  ch=0;
 59                  break;
 60               }
 61           }
 62           if (ch)
 63           {
 64              if (--numh[h[u]]==0) return s;
 65              int q=-1,tmp=t;
 66              for (int i=p[u]; i!=-1; i=e[i].next)
 67              {
 68                  j=e[i].po;
 69                  if (e[i].flow>0&&h[j]<tmp)
 70                  {
 71                     tmp=h[j];
 72                     q=i;
 73                  }
 74              }
 75              cur[u]=q; h[u]=tmp+1;
 76              numh[h[u]]++;
 77              if (u)
 78              {
 79                 u=pre[u];
 80                 neck=d[u];
 81              }
 82           }
 83     }
 84     return s;
 85 }
 86 
 87 bool check(int lim)
 88 {
 89     len=-1; memset(p,255,sizeof(p));
 90     build(1,t,k);
 91     for (int i=1; i<=k; i++) build(0,a[i],1);
 92     for (int i=1; i<=n; i++)
 93         for (int j=0; j<g[i].size(); j++)
 94             build(i,g[i][j],lim);
 95 
 96     if (sap()==k) return 1; return 0;
 97 }
 98 
 99 int main()
100 {
101     int cas;
102     scanf("%d",&cas);
103     while (cas--)
104     {
105         scanf("%d%d%d",&n,&m,&k);
106         for (int i=1; i<=k; i++) scanf("%d",&a[i]);
107         for (int i=1; i<=m; i++)
108         {
109             int x,y;
110             scanf("%d%d",&x,&y);
111             g[x].push_back(y);
112             g[y].push_back(x);
113         }
114         t=n+1;
115         int l=1,r=k,ans=k;
116         while (l<=r)
117         {
118             int mid=(l+r)>>1;
119             if (check(mid))
120             {
121                 ans=mid;
122                 r=mid-1;
123             }
124             else l=mid+1;
125         }
126         printf("%d\n",ans);
127         for (int i=1; i<=n; i++) g[i].clear();
128     }
129 }
View Code

 

posted on 2017-01-07 22:54  acphile  阅读(260)  评论(0编辑  收藏  举报