04 2012 档案
摘要:一看题意,感觉可以用线段树来做,但是二维挺难处理的,后来百度了一下,大牛们是将二维化为一维,因为点已经排好了序,我们就可以省去了一维,只考虑x,然后就是赤裸裸的线段树了,而且还不用事先建树。#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct node{ int x,y;}point[15010];int res[15010],tree[32000*4+10];int insert(int i,int left,int right,int x){ int m
阅读全文
摘要:想一想知道n-1位的结果,如何得到n位的结果呢?假如我们知道n-1的后两位再枚举第n位的数字,不就得到n位的结果了吗?我们用res[n][i][j]表示n位最后两位是i和j;Res[i][j][k]=∑res[i-1][l][j];(其中100*l+10*j+k 是素数)我们还可以优化一下,因为最后一位只有可能是1、3、7、9。所以可以将k和j所在的循环的长度改为4。#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int r
阅读全文
摘要:做了这道题我都快疯了,一开始不是道什么是散列化,看了半天才有点头绪,尝试写了,又遇到了问题,就是排序之后,如何确定新的区间,看看大牛的文章,就是看不懂,今天早上突然,灵光一闪,知道到底怎么回事了,也就是在排序的过程中,记录了染色区间的序号,以便于,散列后重新确定染色区间,就这么简单却弄了那么久,汗颜。后来,没有注意到题中给出的条件 起始点< 终点,是我一直在纠结始点等于终点的情况,唉!还有就是英语本身就不怎么样,竟然还忽略了另一个条件“open interval”,查了一下却是“开区间”的意思,导致我就是弄不明白sample output 中的47 634 是怎么来的,自己总认为是48
阅读全文
摘要:搞了一天终于AC了,感觉题目有点问题,没有说有多个可行顺序的情况如何输出,然而测试数据是按照某一个顺序输出的。比如说:101 010 是按照111222输出,其实(如果题意我没有读错的话)121212 221112应该也是正确的。听说这道题有一定的改动,是不是出题人忽视了呢????令res[i][j]表示串1的前i个字符与串2的前j个字符是否能够按照规则分成两堆。res[i][j]= (res[i-1][j-1] && str1[i]!=str2[j]) || (res[i-2][j] && str1[i]!=str1[i-1]) || (res[i][j-2]
阅读全文
摘要:简单背包,不过直接背包会超时,需要将每一种物品个数转化一下,方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。使这些系数分别为 1,2,4,...,2^(k-1),n[i]-2^k+1,且k是满足n[i]-2^k+1>0的最大整数。例如,如果n[i]为13,就将这种 物品分成系数分别为1,2,4,6的四件物品。代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int coin[7],res
阅读全文
摘要:并查集 讲解看如下博客:http://start07.yo2.cn/articles/ural-1003-parity.html#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define BLOCK 10000int HashTable[20000],father[20000],Rank[20000],N;int Hash(int a){ int i; for(i=1;i<N;i++) if(HashTable[i]==a) return i; HashT
阅读全文
摘要:想了很久,才知道用线段树来做,实现也不算太复杂。#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define SIZE 262145struct node{ int i,left,right,sum;};node vert[SIZE<<2];int treeNode;int build(int i,int left,int right){ int mid; vert[i].left=left; vert[i].right=right; vert[i].
阅读全文
摘要:简单的树形DP,状态转移方程如下:令res[i]表示以i为根的子树获得的最大值;第i个人去或者不去。去的话,res[i]=value[i]+∑res[j], j表示i的孩子的孩子;不去的话,res[i]=∑res[k],k表示i的孩子;因此,res[i]=max{value[i]+∑res[j],∑res[k]};代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAX 123456789struct node{ int i,next;}ve
阅读全文
摘要:令res[i]表示到达第i个站点所用的最小费用;状态转移方程如下:res[i]=min{res[k]+f(L1,L2,L3)};(1<=k<i)代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAX 1234567890int res[10001],dist[10001],L1,L2,L3,C1,C2,C3;int min(int a,int b){ return a < b ? a : b;}int work(int s
阅读全文
摘要:简单的一道DP,只不过是每个状态与三个子状态有关,令res[i][j]表示从第一层到达map[i][j]的最小费用。本应该res[i][j]=min(res[i-1][j],res,[i][j+1],res[i][j-1])+map[i][j];但是在res[i][j+1]是在res[i][j]求出来之后才求出来,那我们怎么办呢?我们可以这样处理:每一行正反各求一次取最小值。#include<iostream>#include<cstdio>#include<cstring>#include<stack>using namespace std;#
阅读全文
摘要:树形DP,令res[i][j]表示以i为根的子树删除j条边所保留的最大苹果数;res[i][j]=max(res[i][j],res[lChild][k]+res[rChild][j-k]+value[i]);(0<=j<=inum[i],0<=k<=inum[lChild])inum[i]表示以i为根的子树树枝的个数,value[i]以i为端点的树枝的苹果树。代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAX
阅读全文
摘要:StaircasesTime Limit: 1.0 second Memory Limit: 16 MBOne curious child has a set of N little bricks (5 ≤ N ≤ 500). From these bricks he builds different staircases. Staircase consists of steps of different sizes in a strictly descending order. It is not allowed for staircase to have steps equal sizes
阅读全文
摘要:K-based NumbersTime Limit: 1.0 secondMemory Limit: 16 MBLet’s consider K-based numbers, containing exactly N digits. We define a number to be valid if its K-based notation doesn’t contain two successive zeros. For example:1010230 is a valid 7-digit number;1000198 is not a valid number;0001235 is not
阅读全文
摘要:一开始自己写了一个状态转移方程用res[i][j][k]表示前i个人已经完成A的j个部分B的k个部分所有过的最少时间。res[i][j][k]=min(res[i][j][k],max(res[i-1][j-s][k-t],s*A[i]+t*B[i]));很显然时间复杂度为O(n^5),显然是不可取的。看了大牛的思想后才知道可以用二分时间+DP来优化:令res[i][j]表示前i个人完成A的j个部分最多能完成B多少。res[i][j]=max(res[i][j],res[i-1][j-k]+(mid-k*A[i])/B[i]);当res[i][j]>=m 说明前i个人可以将任务完成,因此
阅读全文
摘要:状态压缩经典题目令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i][j]表示第i行的第j个状态,kk[i][j]表示第i行第j个状态所放的个数,len[i]表示第i行的可能的状态数。则:res[i][j][k]=max(res[i][j][k],res[i-1][k][l]+kk[i][j]);(0<=l<len[i-2])结果就是:在res[n][j][k]中找一个最大的。状态压缩经典题目令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i]
阅读全文
摘要:令res[i][j]表示从str[i]到str[j]需要添加字符的个数;如果str[k]与str[i]匹配, res[i][j]=min(res[i][j], res[i+1][k-1]+res[k+1][j]);如果str[k]与str[j]匹配, res[i][j]=min(res[i][j],res[i][k-1]+res[k+1][j-1] );如果str[k]与str[i]和str[j]都不匹配,res[i][j]=min(res[i][j],res[i][k-1]+res[k+1][j]+1 );#include<iostream>#include<cstdio&
阅读全文
摘要:令res[i][s1][k]表示第i行状态为s1,前i行摆放棋子的个数为k的方案个数;res[i][s1][k]=∑res[i-1][s2][k-inum]; inum表示第i行摆放的棋子个数,s1,s2表示第i行和第i-1行的状态,两种状态能够相容。#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define lld long long lld res[11][1025][101];int n,m;int init(int j,int state,int inu
阅读全文