上一页 1 ··· 56 57 58 59 60 61 62 63 64 ··· 85 下一页
  2011年12月7日
摘要: UVA_11081 感觉这个题目像是由求两个字符串的组成最长公共子序列的方案种数演变而来的,但上述问题我也没接触过,后来想想把这个题目的一部分剥离出去应该就能解决两个字符串的问题了吧。 我们选择用f1[i][j][k]、f2[i][j][k]分别表示拼到第k个字符时的结尾是第一串的、第二串的,用f[i][j][k]表示总的方案数。那么显然f[i][j][k]=f1[i][j][k]+f2[i][j][k],同时,f1和f2是分开计算的,应该有f1[i][j][k]=f1[i-1][j][k]+(a[i]==c[k]?f[i-1][j][k-1]:0),f2[i][j][k]=f2[i][j.. 阅读全文
posted @ 2011-12-07 21:21 Staginner 阅读(454) 评论(0) 推荐(0) 编辑
摘要: UVA_10280 没想到这个题目用一个剪枝和感觉上复杂度比较大的dp就可以过掉,当然这个题目的复杂度如果真仔细算起来感觉还是比较麻烦的,我在后面也提了几点设想,也许真正的复杂度没有到我们想象得那么大。 先把剪枝放在这里,设limit=min{max*min/(max-min)},那么如果酒量是大于limit的,就必然能够全部装下,否则我们再执行dp。 下面我们开始证明这个剪枝的正确性。我们不妨先对一类瓶子进行讨论,设其最小、最大的装酒量分别是min、max,实际上如果有[x/max]<[x/min],那么酒量x就一定可以全部被装进去,因为满足min*[x/min]<=x<= 阅读全文
posted @ 2011-12-07 19:14 Staginner 阅读(605) 评论(0) 推荐(0) 编辑
摘要: UVA_709 我们不妨用f[i]表示某行到第i个单词结束时的最小的badness,这样f[i]=min{f[i-1]+500,f[j]+badness},当然j+1到i这些单词必须能在这一行放得下。 之后我们不妨先考虑下对于一行而言,单词要怎么摆才最优。不难证明,各个空白的长度差越小越好,并且长度小的空白排在前面。 接下来,我们还要保证全文在满足badness最优的情况下,空白也得最优。如果空白最优,仅就到第i个单词而言,显然行数越少越优,在行数相等的情况下,显然第i个单词所在的这一行的单词数越少越优,于是我们再引入一个记录行数的数组s[]即可。 题目中提到过如果一行只有一个单词,仅... 阅读全文
posted @ 2011-12-07 12:32 Staginner 阅读(434) 评论(0) 推荐(0) 编辑
摘要: UVA_10163 这个题目数据范围比较小,所以一开始我写了M*N*logP的程序也能跑过。先说说二分的思路吧,我们可以二分每个仓库的安全值下限,然后去求最小费用。 后来看了别人的解题报告后发现,可以做两次dp,第一次dp求出最大的安全值下限,第二次dp再根据这个下限求出最小费用。#include<stdio.h>#include<string.h>#define MAXN 110#define MAXM 40#define INF 0x3f3f3f3fint N, M, P, f[MAXM][MAXN], p[MAXM];int init(){ int i, j; s 阅读全文
posted @ 2011-12-07 10:42 Staginner 阅读(360) 评论(0) 推荐(0) 编辑
摘要: UVA_10817 本来一开始没头绪的,后来寝室一哥们问我背包问题是什么,我解释完了之后突然发现这个问题也可以用背包去做。 由于对于每一个应聘的老师要么要要么不要,这就是0-1背包的特点了,剩下的问题是我们是否可以找到一个相当于体积的状态呢。 实际我们可以把每个课程还需几个老师教这一状态看做0-1背包问题的体积,不妨设f[i][j]为取到第i个老师课程状态为j时的最小花费,那么f[i][j]=min{f[i-1][j],f[i-1][k]+w[i]},其中k状态是由j状态加上第i个老师可以教课的状态得到的,如果某项大于2,就当做2来看待,意思是这个老师可以不教这门课。 初始化边界的时候将... 阅读全文
posted @ 2011-12-07 09:04 Staginner 阅读(1027) 评论(2) 推荐(0) 编辑
  2011年12月6日
摘要: UVA_10599 一开始我写的时候把一个点有多个垃圾的情况也考虑进去了,后来交了一下发现是不存在这种情况的。 这个题目由于只能往右走或者往下走,而且路线的不同是以垃圾的位置区分的,那么我们不妨转化成最长上升子序列的问题去处理。 最后为了能明确得出路线的条数,如果终点没有垃圾的话我们不妨把终点也加进去,只不过标记一下这里没有垃圾就可以了,在打印路径的时候不打印出这个点即可。#include<stdio.h>#include<string.h>#define MAXN 110#define MAXD 10010int N, M, g[MAXN][MAXN], p[MAXD 阅读全文
posted @ 2011-12-06 20:48 Staginner 阅读(495) 评论(0) 推荐(0) 编辑
摘要: UVA_11258 用f[i]表示到第i个位置为止分成的数的和的最大值即可。#include<stdio.h>#include<string.h>#define INF 0x7fffffff#define MAXD 210long long int f[MAXD];char b[MAXD];void solve(){ int i, j, k, N; long long int v; scanf("%s", b); N = strlen(b); memset(f, 0, sizeof(f)); for(i = 0; i < N; i ++) { 阅读全文
posted @ 2011-12-06 19:47 Staginner 阅读(334) 评论(0) 推荐(0) 编辑
摘要: UVA_10723 首先这个题目肯定是按最长公共子序列的形式进行dp的,因为只有保证消去的一部分是最长公共子序列才能保证最后生成的序列最短。 因此,在记录方案数的时候我们也按最长公共子序列的生成过程来记录即可,我们不妨用p[i][j]记录最长公共子序列的字符数,用f[i][j]表示到第一个字符串第i个位置、第二个字符串第j个位置时生成的序列最短的方案种数。 当a[i]!=b[j]时,p[i][j]=max{p[i-1][j],p[i][j-1]},那么如果p[i][j]==p[i-1][j],f[i][j]+=f[i-1][j],如果p[i][j]==p[i][j-1],f[i][j]+=.. 阅读全文
posted @ 2011-12-06 17:51 Staginner 阅读(496) 评论(0) 推荐(1) 编辑
摘要: UVA_11008 这个题目由于树的数目很少,我们可以把树的状态压缩成一个整数,并依此来进行状态转移。 为了方面后续的状态转移,我们可以预处理出任意两个树连线上树的分布情况,处理的时候同样选择把状态压缩成一个整数,这样在后面就只需要一个位运算的式子就可以消去这条线上所有的树了。 这样对于一个树林的状态tree,我们就可以枚举其中两棵树,打掉这条线上的所有树就可以了,用记忆化搜索实现起来会比较方便。 此外,最后有可能会出现剩余一棵树的情况,对于这种情况我们没有必要单独列一个每次只打某一棵树的决策,因为如果剩余的不只一棵树,显然这样不是最优的,这样做反而会可能增加很多无用的状态,因此我们用一... 阅读全文
posted @ 2011-12-06 15:51 Staginner 阅读(422) 评论(3) 推荐(0) 编辑
摘要: UVA_10913 为了保证每个格子只走一遍,所以对于每行,我们都从左往右dp一次,再从右往左dp一次,每个格子取两次dp的最大值即可。 如果用递推去做的话,f可以初始化成-INF,但注意只有当前的格子不等于-INF时才进行dp,否则如果下一个格子是正值的话,会当做可以到这个格子,并且路径值是-INF。#include<stdio.h>#include<string.h>#define MAXN 80#define MAXK 10#define INF 0x3f3f3f3fint N, K, a[MAXN][MAXN], f[MAXK][MAXN][MAXN], lef 阅读全文
posted @ 2011-12-06 14:32 Staginner 阅读(425) 评论(0) 推荐(0) 编辑
上一页 1 ··· 56 57 58 59 60 61 62 63 64 ··· 85 下一页