上一页 1 ··· 58 59 60 61 62 63 64 65 66 ··· 85 下一页
  2011年12月2日
摘要: UVA_10891 一开始想到了极大极小的思路,但觉得这不就变成极大极小搜索了么,后来便没继续往下想。 看了别人的题解后发现果然就是极大极小的博弈思想,只不过由于搜索过程中状态有限而且有些状态是重复的,因此可以用记忆化搜索来降低复杂度。当然也可以用递推形式的动规来做。 以后有想法了之后一定要敢于去实现自己的想法。 如果设f[i][j]表示面临由i到j这样一个石子序列所能取得的最大值,那么f[i][j]=max{sum[i][j]-f[i][k],sum[i][j]-f[k][j],sum},其中sum[i][j]表示i到j的值的和,f[i][k]中i<=k<j,f[k][j]中i& 阅读全文
posted @ 2011-12-02 13:56 Staginner 阅读(831) 评论(0) 推荐(0) 编辑
  2011年11月30日
摘要: UVA_10401 这个题目本身并不难,但是如果用gets读的话要注意输入里面有空行。#include<stdio.h>#include<string.h>#include<ctype.h>#define MAXD 20char b[MAXD];int N;long long int f[MAXD][MAXD];void solve(){ int i, j, k, r; long long int res; N = strlen(b); memset(f, 0, sizeof(f)); if(b[0] == '?') { for(i = 0; 阅读全文
posted @ 2011-11-30 19:48 Staginner 阅读(351) 评论(12) 推荐(0) 编辑
摘要: UVA_10313 看了RoBa的题解之后,终于顿悟了。 这个题目涉及到一个结论,用不超过j个硬币凑出面值i的方案种数,是和用面值不超过j的硬币凑出面值i的方案种数是相同的。说得再数学一点,就是整数i拆分成不超过j个整数的拆分数,是和整数i拆成若干个值不超过j的整数的拆分数是相同的。具体的证明用到了Ferrers图像的性质。 这样的话我们就可以取一个二维数组f[i][j]表示用面值不超过j的硬币凑出面值i的方案的种数,那么如果我使用了面值j,对应方案种数就应该加上f[i-j][j],如果我们不使用面值j,那么对应的方案种数就应该加上f[i][j-1]。也就是说状态转移方程为f[i][j]=.. 阅读全文
posted @ 2011-11-30 18:30 Staginner 阅读(797) 评论(0) 推荐(0) 编辑
摘要: UVA_10029 这个题目一开始想转化成最长上升子序列的模型,但发现这样不好做,后来看了别人的题解发现可以转化成找有向无环图的最长路去做。 这样面临的一个问题就是如果显性地建图的话是没办法存下每条边的,于是我们不妨在每次尝试连线的时候再判断这条边是否存在。 为了方便判断两个字符串之间是否有一条有向边,我们不妨以起点为基础,施加3种变换,观察是否可以变换出字典里的字符串,如果可以变换出的话,就说明这两个字符串之间存在一条有向边。 对于判断是否可以变换出字典里的字符串这一步,可以用哈希表也可以二分查找字典。找最长路的过程可以采用记忆化搜索的方式。#include<stdio.h>#i 阅读全文
posted @ 2011-11-30 15:48 Staginner 阅读(861) 评论(7) 推荐(0) 编辑
摘要: UVA_10453 这个题目要求打印最后的结果,所以我们在动规的过程中要记录一下当前的决策,便于我们后面递归去打印回文串。#include<stdio.h>#include<string.h>#define MAXD 1010#define INF 1000000000int N, f[MAXD][MAXD], p[MAXD][MAXD];char b[MAXD];void printpath(int x, int y){ if(x > y) return; if(p[x][y] == 0) { if(x == y) prin... 阅读全文
posted @ 2011-11-30 13:41 Staginner 阅读(391) 评论(0) 推荐(0) 编辑
摘要: UVA_10201 我们不妨用f[i][j]表示到第i个加油站油量为j时这个状态所需的最小花费,那么首先有一部分状态是从第i-1个加油站继承过来的,即f[i][j]=f[i-1][j+d[i]-d[i-1]],之后就是考虑在第i个加油站买多少油会更划算,那么状态转移方程为f[i][j]=min{min{f[i][k]+(j-k)*m[i]},f[i][j]},这样乍看上去是三个for,然而对于min{f[i][k]+(j-k)*m[i]}这个部分,实际上我们也可以写成f[i][k]-k*m[i]+j*m[i],而f[i][k]-k*m[i]这个部分仅和k有关,我们可以在循环j的时候顺便记录下最 阅读全文
posted @ 2011-11-30 13:06 Staginner 阅读(497) 评论(0) 推荐(0) 编辑
摘要: UVA_10154 首先,我们不妨证明一下这个命题,如果一个力量小的乌龟可以驮着一个力量大的乌龟,那么这个力量大的乌龟也必然可以驮起这个力量小的乌龟,而且还能够使两个乌龟上方增加承重能力。 我们不妨设力量小的乌龟的重量和力量分别为w1、s1,而力量大的乌龟为w2、s2,由于乌龟1可以驮起乌龟2,那么有s1>=w1+w2,如果我们假设乌龟2驮不起乌龟1,那么就应该有s2<w1+w2,然而我们知道乌龟2的力量更大,所以应该有s2>s1>=w1+w2,这样就产生矛盾了,原命题得证。 接着,如果乌龟1在乌龟2的下面,两龟上方的承重能力至多为s1-(w1+w2)。然而如果换成乌龟 阅读全文
posted @ 2011-11-30 01:27 Staginner 阅读(1030) 评论(0) 推荐(0) 编辑
  2011年11月29日
摘要: UVA_11137 这个题目实际上就是一个多重背包问题,只不过要求记录的是方案的种数。#include<stdio.h>#include<string.h>#define MAXD 10010int N;long long int f[MAXD];void solve(){ int i, j, k; memset(f, 0, sizeof(f)); for(i = 0; i <= N; i ++) f[i] = 1; for(i = 2; i <= 21; i ++) { k = i * i * i; for(j = k;... 阅读全文
posted @ 2011-11-29 20:42 Staginner 阅读(197) 评论(0) 推荐(0) 编辑
摘要: UVA_10617 这个题目可以用区间动规去处理。 我们设f[i][j]为字符串i到j这个区间内回文串的个数,那么如果b[i]==b[j],f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+f[i+1][j-1]+1=f[i+1][j]+f[i][j-1]+1,也就是说f[i][j]包括4个部分,第一部分是b[i]和中间的字符形成的回文串,第二部分是b[j]和中间的字符形成的回文串,这两部分也就等于区间[i,j-1]内的回文串的个数加上[i+1,j]内回文串的个数再减去区间[i+1,j-1]内的回文串的个数,也就是f[i+1][j]+f[i][j-1]-f[i.. 阅读全文
posted @ 2011-11-29 20:04 Staginner 阅读(491) 评论(4) 推荐(0) 编辑
摘要: UVA_10271 总的来讲,我们应该从大到小去安排筷子,因为如果从小到大去安排的话,最后剩下的不一定可以作为最长的那根。 我首先将筷子反过来存在了数组a[]里面,这样用f[i][j]表示一共有到第i根这么多的筷子安排给j个人的最小的badness,那么如果3*j==i+1,f[i][j]=f[i-2][j-1]+(a[i–1]–a[i])*(a[i-1]-a[i]),否则f[i][j]=min{f[i][j-1],f[i-2][j-1]+ (a[i–1]–a[i])*(a[i-1]-a[i])},当然3*j<=i+1且j<=K+8。#include<stdio.h># 阅读全文
posted @ 2011-11-29 17:04 Staginner 阅读(366) 评论(4) 推荐(0) 编辑
上一页 1 ··· 58 59 60 61 62 63 64 65 66 ··· 85 下一页