模拟赛#4
A.HDU 1171
把和拆一半作容量然后跑背包。
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cmath>
5 #include <cstring>
6 #include <queue>
7 #include <map>
8 #define ll long long
9 #define out(a) printf("%d ",a)
10 #define writeln printf("\n")
11 const int N=3e5+50;
12 using namespace std;
13 int n;
14 int a[N],b[N];
15 int f[N];
16 int sum,num;
17 int read()
18 {
19 int s=0,t=1; char c;
20 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
21 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
22 return s*t;
23 }
24 ll readl()
25 {
26 ll s=0,t=1; char c;
27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
29 return s*t;
30 }
31 int main()
32 {
33 while (~scanf("%d",&n)){
34 if (n<=0) break;
35 memset(f,0,sizeof(f)); sum=num=0;
36 for (int i=1;i<=n;i++)
37 a[i]=read(),b[i]=read(),sum+=a[i]*b[i];
38 num=sum;
39 sum/=2;
40 for (int i=1;i<=n;i++)
41 for (int j=1;j<=b[i];j++)
42 for (int k=sum;k>=a[i];k--)
43 f[k]=max(f[k],f[k-a[i]]+a[i]);
44 out(max(f[sum],num-f[sum])); cout<<min(num-f[sum],f[sum]);
45 writeln;
46 }
47 return 0;
48 }
B.HDU 2962
最短路,但是每条道路有高度限制,求车的最大高度和限制下的最短路.
很容易想到二分答案最大高度,然后用一个最短路算法看看能不能跑到终点,我写的是Dijkstra+堆优化。
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cmath>
5 #include <cstring>
6 #include <queue>
7 #include <map>
8 #define ll long long
9 #define out(a) printf("%d ",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 int n,m,s,t;
14 int x,y,z,h,now,ans,cnt=0,tot=0;
15 int l,r,mid;
16 int head[N],dis[N];
17 bool vis[N],flag;
18 int read()
19 {
20 int s=0,t=1; char c;
21 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
22 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
23 return s*t;
24 }
25 ll readl()
26 {
27 ll s=0,t=1; char c;
28 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
29 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
30 return s*t;
31 }
32 struct node
33 {
34 int to,cost,cost2,len,next;
35 int h,id;
36 bool operator<(const node& a)const{
37 return h>a.h;
38 }
39 }edge[N];
40 priority_queue<node> q;
41 void add(int x,int y,int h,int z)
42 {
43 edge[++tot].to=y;
44 edge[tot].cost=z;
45 edge[tot].cost2=h;
46 edge[tot].next=head[x];
47 head[x]=tot;
48 }
49 void Dijkstra(int s,int limit)
50 {
51 int x,num; node p;
52 memset(dis,0x3f,sizeof(dis));
53 memset(vis,false,sizeof(vis));
54 dis[s]=0; p.h=0,p.id=s; q.push(p);
55 while (!q.empty()){
56 p=q.top(); q.pop(); x=p.id;
57 if (!vis[x]) {
58 vis[x]=true;
59 for (int i=head[x];i;i=edge[i].next){
60 if (edge[i].cost2!=-1&&edge[i].cost2<limit) continue;
61 int y=edge[i].to,z=edge[i].cost;
62 if (dis[y]>dis[x]+z){
63 dis[y]=dis[x]+z;
64 p.h=dis[y]; p.id=y;
65 q.push(p);
66 }
67 }
68 }
69 }
70 }
71 int main()
72 {
73 while (~scanf("%d%d",&n,&m)){
74 if (n==0&&m==0) break;
75 else if (cnt) writeln; flag=false; ans=0;
76 memset(edge,0,sizeof(edge)); memset(head,0,sizeof(head));
77 printf("Case %d:",++cnt); writeln;
78 tot=0;
79 for (int i=1;i<=m;i++){
80 x=read(),y=read(),h=read(),z=read();
81 add(x,y,h,z),add(y,x,h,z);
82 }
83 s=read(),t=read(),r=read();
84 l=1;
85 while (l<=r){
86 mid=(l+r)>>1;
87 Dijkstra(s,mid);
88 //out(mid),out(dis[t]),writeln;
89 if (dis[t]==1061109567) r=mid-1;
90 else {
91 l=mid+1;
92 flag=true;
93 ans=dis[t];
94 }
95 }
96 if (flag){
97 printf("maximum height = %d",r); writeln;
98 printf("length of shortest route = %d",ans);
99 writeln;
100 }
101 else printf("cannot reach destination");
102 }
103 return 0;
104 }
C.HDU 1081
常规DP。。
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cmath>
5 #include <cstring>
6 #include <queue>
7 #include <map>
8 #define ll long long
9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 int n,m,ans,sums;
14 int a[150][150],sum[150][150];
15 int read()
16 {
17 int s=0,t=1; char c;
18 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
19 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
20 return s*t;
21 }
22 ll readl()
23 {
24 ll s=0,t=1; char c;
25 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
26 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
27 return s*t;
28 }
29 int main()
30 {
31 while (scanf("%d",&n)!=EOF){
32 ans=-233333;
33 for (int i=1;i<=n;i++)
34 for (int j=1;j<=n;j++)
35 a[i][j]=read(),a[i][j]+=a[i-1][j];;
36 for(int i=0;i<=n;i++)
37 for(int j=i+1;j<=n;j++) {
38 int sums=0;
39 for(int k=1;k<=n;k++) {
40 sums+=a[j][k]-a[i][k];
41 if(sums<0) sums=0;
42 else ans=max(ans,sums);
43 }
44 }
45 out(ans); writeln;
46 }
47 return 0;
48 }