习题选讲
-
Upload
alfonso-collins -
Category
Documents
-
view
52 -
download
7
description
Transcript of 习题选讲
![Page 2: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/2.jpg)
2 2011-12-21
动态规划 Pick numbers The Top-Code 过河 The Longest Walk Hie with the Pie 电子眼 Fight Club GECKO 能量项链 Antimonotonicity Missile Bridging Signals
![Page 3: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/3.jpg)
3 2011-12-21
动态规划 Counting Problem HOUSING Circular Sequence Apple Tree Maximum Sum 金明的预算方案 运动会 Cash Machine 开心的金明 Knapsack Dairy Queen
![Page 4: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/4.jpg)
4 2011-12-21
Pick numbers题目大意:给一个M*N的格子,现在需要从左上角走到右下角,并且只能往下或往右走,并且要把走过的格子中的数加起来,现在要求和为正并且越小越好,求和。
2<=M,N<=10,格子中的数范围为 [-10,10]
![Page 5: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/5.jpg)
5 2011-12-21
Pick numbers解题思路:因为只能往下和往右走,因此走第二行的格子必定在走第一行的格子之后,在同一行里,靠左的格子必定先走。
从左上角到右下角总共经过 M+N-1个格子,因此得到的和的范围为 [-190,190]。
![Page 6: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/6.jpg)
6 2011-12-21
Pick numbers使用动态规划,按走的顺序记录到达每个格子可能出现的所有的和。
每个格子使用一个数组,如果某个和可能出现,则这个位置标为 true。
每个格子可能出现的和,只可能从它的左方或上方格子可能出现的和,加上当前格子的值得到。
![Page 7: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/7.jpg)
7 2011-12-21
Pick numbers mid=200; ans=-1; dp[1][1][mid+a[1][1]]=true; for (i=1;i<=m;i++) for (j=1;j<=n;j++) if (i!=1||j!=1) for (k=0;k<=mid+mid;k++) { if (dp[i-1][j][k]) dp[i][j][k+a[i][j]]=true; if (dp[i][j-1][k]) dp[i][j][k+a[i][j]]=true; } for (k=mid+1;k<=mid+mid;k++) if (dp[m][n][k]) { ans=k-mid; break; }
![Page 8: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/8.jpg)
8 2011-12-21
The Top-Code
题目大意:给出一个字符串,要求把它切成长度不小于 2的几段,使得每一段的字典序比它前一段的字典序小,求最大能切成的段数,在当前段数下的方案数,在当前段数下字典序最小的方案。
字符串长度不超过 100。
![Page 9: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/9.jpg)
9 2011-12-21
The Top-Code
解题思路: 动态规划。每次要切新的一段,能切出的字符串只决定于上一个切出来的字符串。
状态 dp[i][j], i表示上一个字符串起始位置, j表示当前字符串起始位置。状态转移时,枚举当前字符串长度,并与上一个字符串长度逐个比较,确定是否能转移。
转移过程中更新最多段数,和到达最多段数的方法数,并把所有可行转移边记录下来。
寻找字典序最小方案时,从结束状态开始,沿着转移边反向寻找到所有可能经过的状态,再从起始状态开始,只沿可能经过的状态贪心转移,最终到达结束状态。
http://222.200.182.58/viewsource.php?sid=1095986
![Page 10: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/10.jpg)
10 2011-12-21
过河题目大意:桥的起点为 0,终点为 L,其中地有M个石子。青蛙每次跳的范围为 [S,T],问要跳过桥最小踩到石子次数。
1 <= L <= 10^9 1 <= S <= T <= 10 1 <= M <= 100
![Page 11: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/11.jpg)
11 2011-12-21
过河 解题思路: L的值大太,直接按 L的值进行动态规划不可行。
分情况:若 S和 T相等,则踩到的石子数是固定的;
若 S和 T不相等,因为 S和 T的最大值为 10,所以当两个石子相差太远是没有意义的,这里取的值为 90,当石子距离相差 90以上时,看作90,答案不变。
压缩后桥长度不超过 10000,直接动态规划即可。
![Page 12: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/12.jpg)
12 2011-12-21
过河 for(i=0;i<m;i++) { delta[i]=rock[i+1]-rock[i]; if(delta[i]>90)delta[i]=90; } for(i=1;i<=m;i++) rock[i]=rock[i-1]+delta[i-1]; for(i=1;i<=m;i++) dp[rock[i]]=1; f[0]=1; work();
![Page 13: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/13.jpg)
13 2011-12-21
过河 void work() { L=rock[m]+90; for(i=s;i<=L;i++) { max=101; for(j=i-t;j<=i-s;j++) if(j>=0) if(f[j]&&dp[j]+dp[i]<max) { max=dp[j]+dp[i]; f[i]=1; } dp[i]=max; } }
![Page 14: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/14.jpg)
14 2011-12-21
The Longest Walk
题目大意:给出一个图,求出不经过重复点最长路径。
隐藏条件:图的点数不超过 12。
![Page 15: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/15.jpg)
15 2011-12-21
The Longest Walk
解题思路: 动态规划,状态为已经经过哪些点,当前所在位置。
状态转移,在当前状态可以到达哪个没有到达过的点,到达新的状态,并纪录转移。
输出路径时,从结束结点开始,按照纪录的转移倒推输出。
如果状态转移是倒推的,则输出的结果不需再倒推。
![Page 16: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/16.jpg)
16 2011-12-21
The Longest Walk
for(i=1;i<20;i++) t[i]=t[i-1]*2; for(i=1;i<t[n];i++)for(j=0;j<n;j++){ if((i&t[j])==0) continue; for(k=0;k<n;k++){ if(j==k||(i&t[k])==0) continue; if(b[j][k]&&a[j][i]<b[j][k]+a[k][i-t[j]]){ a[j][i]=b[j][k]+a[k][i-t[j]]; suc[j][i]=k; } } }
![Page 17: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/17.jpg)
17 2011-12-21
Hie with the Pie
题目大意:给出一个图,求出从起点经过所有点并回到起点的最短路径,可以经过重复点。
点数不超过 10。
![Page 18: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/18.jpg)
18 2011-12-21
Hie with the Pie
解题思路: 动态规划,状态为已经经过哪些点,当前所在位置。
状态转移,在当前状态可以到达哪个没有到达过的点,到达新的状态,并纪录转移。
因为可以经过重复点,先调用 floyd算法求出所有点之间的最短路。
![Page 19: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/19.jpg)
19 2011-12-21
Hie with the Pie for(int state=opt[0][1<<0]=0;state<(1<<n);state++) for(i=0;i<n;i++) if((state&(1<<i))&&opt[i][state]!=-1) { for(j=0;j<n;j++) { int newstate=state|(1<<j); if(opt[j][newstate]==-1 ||opt[j][newstate]>opt[i][state]+g[i][j]) opt[j][newstate]=opt[i][state]+g[i][j]; } } int ans=opt[0][(1<<n)-1];
![Page 20: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/20.jpg)
20 2011-12-21
电子眼题目大意:一个城市有 N条马路和 N个路口,在路口安装一个电子眼可以监视和它连接的马路,问最小需要多少电子眼才可以监视所有马路。
1<=N<=100000
![Page 21: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/21.jpg)
21 2011-12-21
电子眼 解题思路: N个结点 N-1条边的连通图是树,则 N个结点 N条边的连通图只存在一个环。
假设题目所求的图是树,则可以用树型动态规划解决:从一个结点开始,当前结点包括的状态是,如果子结点连向它的边全部已经被监视需要的电子眼数,和存在还没被监视的边需要的电子眼数,则可先递归算出子结点的信息,在转移时,如果存在边还没被监视,则当前结点必须安装,否则可以安装也可以不安装,取最小值。
当图存在一个环的时候,可以找到环中的一条边,分别假设这条边的其中一个结点是否安装电子眼,并分别求解。
![Page 22: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/22.jpg)
22 2011-12-21
电子眼 void dfs(long k,long &x1,long &y1,long &x2,long &y2) { long temp,nextx1,nexty1,nextx2,nexty2; x1=x2=0; y1=y2=1; for (node* pp=b[k];pp!=NULL;pp=pp->next) { temp=pp->xx; if ((temp==p&&k==q)||(temp==q&&k==p)); else if (d[temp]==0) { d[temp]=1; dfs(temp,nextx1,nexty1,nextx2,nexty2); x1+=nexty1; x2+=nexty2; if (nextx1<nexty1) y1+=nextx1; else y1+=nexty1; if (nextx2<nexty2) y2+=nextx2; else y2+=nexty2; } } if (k==q) x1=y2=1000000; }
![Page 23: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/23.jpg)
23 2011-12-21
Fight Club
题目大意: N个人站成一圈,每个人都只能与相邻的人战斗,输的人离开这个圈,直到圈里只剩下一个人。给出每两个人之间的战斗胜负关系表,求出每个人是否能成为圈里剩下的唯一一个人。
![Page 24: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/24.jpg)
24 2011-12-21
Fight Club 解题思路: 要成为圈中唯一剩下的人,则其他人全部都要打败,而每个人只能与旁边的人战斗,因此对于每个状态下每个人只关心两边的人。
动态规划,状态为区间 [i,j],表示从第 i个人逆时针方向数到第 j个人之间所有人(不包括 i和 j)都已经被打败。
状态转移,每个区间 [i,j]能够达到,则需要在 i和 j之间存在一个人 k,使得 [i,k]能够成立,且 [k,j]能够成立,且 k会被 i和 j其中一个人打败。
初始时长度为 0的区间必定成立,且长度较大的区间需要长度较小的区间得到,因此枚举顺序为区间的长度从小到大。
最后对于每个人 i,如果 [i,i]成立,则表示所有其它人都被打败。
![Page 25: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/25.jpg)
25 2011-12-21
Fight Club memset(f, 0, sizeof(f)); for (int i=0; i<n; i++) f[i][(i+1)%n] = 1; for (int d=2; d<=n; d++) for (int i=0; i<n; i++) { int j = (i+d)%n; for (int k=(i+1)%n; k!=j; k=(k+1)%n) if (f[i][k] && f[k][j] && (a[i][k] || a[j][k])) { f[i][j] = 1; break; } }
![Page 26: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/26.jpg)
26 2011-12-21
GECKO
题目大意: 一只壁虎在墙上的格子爬,每个格子上有不同数量的蚊子。壁虎只能从第一行格子开始,每一次爬动都只能爬到下一行格子,只能爬到它所在格子的下一行位置或旁边位置的格子。它每到达一个格子就把格子中的蚊子吃了。问最多能吃的蚊子数量。
格子的行数和列数不超过 500。
![Page 27: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/27.jpg)
27 2011-12-21
GECKO
解题思路: 动态规划,状态为一个格子,如果壁虎现在在这个格子里,它最多已经吃了的蚊子数量。
状态转移,对于每一个格子,都只能从上一行的三个格子转移过来,取其中的最大值即可。
按行的顺序枚举。
![Page 28: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/28.jpg)
28 2011-12-21
GECKO
for (i=1;i<h;i++) { a[i][0]+=max(a[i-1][0],a[i-1][1]); for (j=1;j<w-1;j++) a[i][j]+=max(a[i-1][j-1],a[i-1][j],a[i-1][j+1]); a[i][w-1]+=max(a[i-1][w-1],a[i-1][w-2]); }
![Page 29: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/29.jpg)
29 2011-12-21
能量项链题目大意:给出一串项链,每次可以选相邻两个珠子进行聚合,释放出一定的能量,并产生一个新珠子。项链是头尾相接的。求释放的能量的总和的最大值。
项链长度不超过 100。
![Page 30: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/30.jpg)
30 2011-12-21
能量项链 解题思路: 每次聚合,都会使数字中一的个数字消失。 动态规划,状态为 [i,j]表示从 i开始,按顺时针方向到 j,这一段珠子所聚合得到的能量最大值。
状态转移,要求出 [i,j]的值,则存在一个 k在 i和 j之间, [i,j]的值为 [i,k]的值与 [k+1,j]的值与这次聚合所释放出的能量的总和,取最大值。
且长度较大的区间需要长度较小的区间得到,因此枚举顺序为区间的长度从小到大。
![Page 31: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/31.jpg)
31 2011-12-21
能量项链 for (step=1;step<n;step++) for (i=0;i<n*2;i++) { j=i+step; if (j>=n*2) break; for (k=i;k<j;k++) temp=ans[i][k]+ans[k+1][j]+a[i]*a[k+1]*a[j+1]; if (ans[i][j]<temp) ans[i][j]=temp; }
![Page 32: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/32.jpg)
32 2011-12-21
Antimonotonicity Missile
题目大意:给出一列数,现在要找出最长的子序列,满足第一个数大于第二个数,第二数小于第三个数,第三个数大于第四个数,如此类推。
![Page 33: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/33.jpg)
33 2011-12-21
Antimonotonicity Missile
解题思路: 动态规划,状态为在当前的数字,最长的子序列长度。
状态转移,若在原数列中,当前数字比上一个数字小,若子序列长度为奇数,则可加上当前数字,若子序列长度为偶数,则可用当前数字替换上一个数字,长度不变;若当前数字比上一个数字大,也可同理。
![Page 34: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/34.jpg)
34 2011-12-21
Antimonotonicity Missile
l=1; for (i=2;i<=n;i++) { if (a[i]<a[i-1]&&l%2==1) l++; else if (a[i]>a[i-1]&&l%2==0) l++; }
![Page 35: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/35.jpg)
35 2011-12-21
Bridging Signals
题目大意:左边有一列 p个数,右边有一列 p个数,并给出它们之间的连线情况,问最多可以保留多少个连线,使到中间的连线不会出现交叉。
P<40000
![Page 36: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/36.jpg)
36 2011-12-21
Bridging Signals 解题思路: 要求最大的不交叉连线数量,问题等价于求最长上升子序列。
最长上升子序列动态规划解法: 状态,以当前数字为子序列的最后一个数,则子序列的最大长度;
状态转移,对每个数字,找出在这个数字之前出现并且比它小的所有数字,并且从其中找出长度最大的数,加上一即是当前数字的最大子串长度。
D[i]=max{1,D[j]+1} j=1,2,...,i-1 并且 A[i]>A[j] 复杂度 O(N^2)
通过以上解法可以改进成 O(NlogN)的。按数字大小建立线段树,那么在线段树上的操作只有插入一个数和查找某个区间的最大值,可以实现。
![Page 37: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/37.jpg)
37 2011-12-21
Bridging Signals 最长上升子序列的其它解法: 维护一个一维数组,数组里的第 i个数表示最长上升子序列长度是 i的所有子序列中末尾最小的那个数。因此这个数组是递增的。按顺序插入每一个数的时候,在数组中找到比它大的最小的数,并更新这个位置;如果它比所有数都大,增数组长度增加一,并把它放在最末端。寻找的时候使用二分查找。
最后的最大长度等于数组长度。复杂度 O(NlogN) 例如,原序列为 1 , 5 , 8 , 3 , 6 , 7 数组为 1 , 5 , 8 ,此时读到 3 ,用 3 替换 5 ,得到 1 ,
3 , 8 ; 再读 6 ,用 6 替换 8 ,得到 1 , 3 , 6 ;再读7 ,得到最终数组为 1 , 3 , 6 , 7 。最长递增子序列为长度 4 。
![Page 38: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/38.jpg)
38 2011-12-21
Bridging Signals nn=0;c[0]=0; for (i=1;i<=n;i++) { if (a[i]>c[nn]) { c[++nn]=a[i]; b[i]=nn; } else { hi=upper_bound(c,c+nn+1,a[i])-c; c[hi]=a[i]; b[i]=hi; } }
![Page 39: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/39.jpg)
39 2011-12-21
Counting Problem
题目大意: 一个 N*N的棋盘,在里面放棋子,使得每行有且只有两个棋子,每列有且只有两个棋子,问有多少种方法。通过交换两行或交换两列的方法得到相同的棋盘看作同一种。
N<=500
![Page 40: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/40.jpg)
40 2011-12-21
Counting Problem
解题思路:问题可转化为把 N分解成大于 2的整数之和有多少种分法。
动态规划,状态 a[i][j]表示把 i分解成大于j的整数之和有多少种分法。
状态转移, a[i][j]=sum(a[i-k][k])(k>=j)。
![Page 41: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/41.jpg)
41 2011-12-21
Counting Problem for (i=0;i<=500;i++) { for (j=0;j<=500;j++) { if (i==0) a[i][j]=1; else if (i<j) a[i][j]=0; else { a[i][j]=0; for (k=max(2,j);k<=i;k++) a[i][j]=(a[i][j]+a[i-k][k])
%1000007; } } ans[i]=a[i][2]; }
![Page 42: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/42.jpg)
42 2011-12-21
HOUSING
题目大意: N个人分到屋里,每间房至少 5个人,有多少种分法?
5 <= n <= 100
![Page 43: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/43.jpg)
43 2011-12-21
HOUSING
解题思路:问题可转化为把 N分解成大于 5的整数之和有多少种分法。
和上题一样。
![Page 44: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/44.jpg)
44 2011-12-21
HOUSING for (i=0;i<=100;i++) { for (j=0;j<=100;j++) { if (i==0) a[i][j]=1; else if (i<j) a[i][j]=0; else { a[i][j]=0; for (k=max(5,j);k<=i;k++) a[i][j]=a[i][j]+a[i-k][k]; } } ans[i]=a[i][5]; }
![Page 45: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/45.jpg)
45 2011-12-21
Circular Sequence
题目大意:有一个长度为 n的循环队列,求出一个和最大的连续子串。
1<=n<=100000
![Page 46: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/46.jpg)
46 2011-12-21
Circular Sequence 解题思路: 首先判断序列中是否全部都是负数,如果是的话,最大和即为最大的负数。
如果序列并不是循环的,有已知的 O(n)方法求出最大值。
int cal() { int answer=0,sum=0; for (int i=0;i<n;i++) { sum+=i; if (sum>ans) ans=sum; if (sum<0) sum=0; }
![Page 47: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/47.jpg)
47 2011-12-21
Circular Sequence
则求循环队列的最大值,可以当作不循环队列,可能是最大和,也可能是总和减去最小和。
sum1=cal(); for (i=0;i<n;i++) { sum+=a[i]; a[i]=-a[i]; } sum2=sum+cal(); return max(sum1,sum2);
![Page 48: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/48.jpg)
48 2011-12-21
Apple Tree
题目大意:有一棵苹果树有 N个结点,每个结点上有苹果,最多可以沿着苹果树的边走 K步,每走过一个结点把上面的苹果吃掉。问最多可以吃多少个苹果。
1<=N<=100, 0<=K<=200
![Page 49: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/49.jpg)
49 2011-12-21
Apple Tree
解题思路: 使用树型动态规划,每个结点的状态为,以这个结点为根的子树上使用不同步数,并且是否会回来原结点,所吃的苹果的最大值。
状态转移,每个结点,对于每个子结点,可以枚举分配多少步数到这个子结点上。
http://222.200.182.58/viewsource.php?sid=102025
![Page 50: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/50.jpg)
50 2011-12-21
Maximum Sum
题目大意:有一个数列,求出两个连续的子序列,使得它们的和最大。
![Page 51: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/51.jpg)
51 2011-12-21
Maximum Sum
解题思路:现在已知求一列数的一个连续子序列最大和的方法,因此可以求出从左边数起的任意一个子段的连续子序列最大和,再求出从右边数起的,再枚举中间切开数列的位置,把左右两部分加起来,即可得到答案。
![Page 52: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/52.jpg)
52 2011-12-21
Maximum Sum sum=ans=0; for (i=0;i<n;i++) { sum+=a[i]; if (sum>ans) ans=sum; if (sum<0) sum=0; s1[i]=ans; } sum=ans=0; for (i=n-1;i>=0;i--) { sum+=a[i]; if (sum>ans) ans=sum; if (sum<0) sum=0; s2[i]=ans; }
![Page 53: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/53.jpg)
53 2011-12-21
Maximum Sum
ans=0; for (i=1;i<n;i++) if (s1[i-1]+s2[i]>ans) ans=s1[i-1]+s2[i];
![Page 54: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/54.jpg)
54 2011-12-21
Knapsack
题目大意:给出背包的容量,给出各种物品大小,求在不超过背包容量情况下的最大占用体积。
![Page 55: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/55.jpg)
55 2011-12-21
Knapsack 解题思路: 0-1背包问题裸题。scanf("%d%d", &n, &m);for (int i=0; i<n; i++) scanf("%d", w+i);
//dpfill(f, f+m+1, 0);f[0] = 1;for (int i=0; i<n; i++) for (int j=m-w[i]; j>=0; j--) if (f[j]) f[j+w[i]] = 1; int ans;for (ans = m; !f[ans]; ans--);
![Page 56: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/56.jpg)
56 2011-12-21
开心的金明 题目大意: 金明想买一些物品(不超过M件),第 j件物品的价格为 v[j],重要度为 w[j].他希望在不超过 N元(可以等于 N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
请你帮助金明设计一个满足要求的购物单。
![Page 57: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/57.jpg)
57 2011-12-21
开心的金明解题思路:这题是 0-1背包问题。
![Page 58: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/58.jpg)
58 2011-12-21
开心的金明while (cin>>n>>m){
//readfor (int i=1; i<=m; i++) cin>>v[i]>>p[i];
//initializefor (int j=0; j<=m; j++) f[0][j]=0;for (int i=0; i<=n; i++) f[i][0]=0;//dpfor (int i=1; i<=n; i++) { for (int j=1; j<=m; j++) { if (i-v[j]>=0) {
f[i][j]=max(f[i][j-1], f[i-v[j]][j-1]+v[j]*p[j]);
} else { f[i][j]=f[i][j-1]; } }}//outputcout<<f[n][m]<<endl;
}
![Page 59: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/59.jpg)
59 2011-12-21
运动会题目大意:一个人去参加运动会,一天最多参加一个项目,并且参加的项目消耗的精力总和不能超过他的总精力,赢得的项目有奖金。求最大的奖金数量。
![Page 60: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/60.jpg)
60 2011-12-21
运动会解题思路:分组背包,对每一天,选项为可以参加任意一场比赛,也可以不参加比赛。
![Page 61: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/61.jpg)
61 2011-12-21
运动会 memset(a,0,sizeof(a)); i=k=0; while (k<n) { if (i<d[k]) i++; for (j=0;j<=p;j++) { if (i<d[k]) a[i+1][j]=a[i][j]; else { a[i+1][j]=max(a[i][j],a[i+1][j]); if (j+e[k]<=p&&a[i][j]+m[k]>a[i+1][j+e[k]]) a[i+1][j+e[k]]=a[i][j]+m[k]; } } if (i>=d[k]) k++; }
![Page 62: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/62.jpg)
62 2011-12-21
Cash Machine
题目大意:一台机器里有 N种纸币,每种纸币有不同的面额和对应的数量。再给出一个额度,问不超过这个额度能得到最大的数量是多少。
![Page 63: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/63.jpg)
63 2011-12-21
Cash Machine
解题思路:使用动态规划,状态为当前金额是否能取到,并且最后是通过拿多少张何种面额的纸币得到。
状态转移,如果某状态在当前面额的纸币上没有拿完,则可以继续拿,并对相应的金额更新答案。
![Page 64: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/64.jpg)
64 2011-12-21
Cash Machine //input scanf("%d", &n); for (int i=0; i<n; i++) scanf("%d %d", a+i, b+i); //dp memset(f, 0, sizeof(f)); f[0] = 1; for (int i=0; !f[m] && i<n; i++) for (int j=m; !f[m] && j>=0; j--) if (f[j]) { for (int k=1; k<=a[i]; k++) { int x = j+k*b[i]; if (x>m || f[x]) break; f[x] = 1; } } //output while (!f[m] && m>0) m--; printf("%d\n", m);
![Page 65: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/65.jpg)
65 2011-12-21
Dairy Queen
题目大意:给出一些硬币的面额,不限数量,给出一个金额,问组成的方法数有多少种。
![Page 66: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/66.jpg)
66 2011-12-21
Dairy Queen 解题思路: 对每种硬币,若面额为 C,并且在这之前能构成金额 j(包括 C),则加上这种硬币能构成金额 j+C,即 j的方案数累加到 j+C上。 int i, j;
memset(dp, 0, sizeof(dp)); dp[0] = 1; for (i = 0; i < c; i++) { int t = c_i[i]; for (j = 1; j <= n; j++) { if (t <= j) dp[j] += dp[j - t]; } } // answer is dp[n];
![Page 67: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/67.jpg)
67 2011-12-21
金明的预算方案题目大意:金明想买东西,但价格不能超过 N。物件分成主件和附件,要先买了主件才能买附件。每个物品有重要度,现在所买的物品的价格与重要度的乘积的和最大。
每个主件最多有两个附件。
![Page 68: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/68.jpg)
68 2011-12-21
金明的预算方案解题思路:这题是变种的 0-1背包问题。把每个主件看作一个物体,而取的方法包括 {不取,只取主件,取主件和附件 1,取主件和附件2,取主件和两个附件 },然后用解决背包问题的方法解决。
![Page 69: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/69.jpg)
69 2011-12-21
金明的预算方案 for (i=1;i<=m;i++) { if (q[i]!=0) { for (j=0;j<=n;j++) b[j][i]=b[j][i-1]; } else { for (j=0;j<=n;j++) { b[j][i]=b[j][i-1]; for (k=0;k<4;k++) { if (j>=c[k][i]&&a[k][i]+b[j-c[k][i]][i-1]>b[j][i]) b[j][i]=a[k][i]+b[ j-c[k][i] ][i-1]; } } } }
![Page 70: 习题选讲](https://reader035.fdocument.pub/reader035/viewer/2022062719/5681309c550346895d968692/html5/thumbnails/70.jpg)
70 2011-12-21
谢谢!