10 2012 档案

摘要:题意:给定一棵树,求切出有n个结点的子树至少要切几条边。解法:dp[i][j]记录使得以i为根的子树有j个结点最少要切几条边 dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[son[i]][k]) 最后统计答案时要注意,如果不是根节点还要+1...切掉这个节点与其父亲之间的边 1 #include<iostream> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 #define N 200 6 using namespace std; 7 co 阅读全文
posted @ 2012-10-31 19:48 silver__bullet 阅读(202) 评论(0) 推荐(0)
摘要:250pt.题意:给定n块砖,编号0~n-1,选一定的砖摞起来,要求上面的砖编号比下面的大,并且偶数高度的不能放在奇数高度的上面,求最大高度。解法: dp[i][0]记录选完前i块并且此时最上面一块高度为偶数的最优解 dp[i][1]记录选完前i块并且此时最上面一块高度为奇数的最优解。。。250pt 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #define N 100 7 阅读全文
posted @ 2012-10-31 16:39 silver__bullet 阅读(202) 评论(0) 推荐(0)
摘要:题目描述:...解法: 树形dp+分组背包。 dp[i][j]记录以i为根的子树分配j个用户时的最大收益,cnt[i]记录以i为根的子树有几个叶子节点,对于每个i,背包容量即为cnt[i]的大小。 将i的每个子节点看作一组,这组背包的物品重量即为1~cnt[son[i]],由于只能从每组中选出一种物品,所以可以看做分组背包。 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #define N 3010 6 using names 阅读全文
posted @ 2012-10-29 21:31 silver__bullet 阅读(172) 评论(0) 推荐(0)
摘要:题目描述:求小于n且与n不互质的数的和。分析: 方法一:容斥原理。对n分解因式,利用容斥原理来n的因子的和即为答案。 方法二:考虑欧拉函数,n之前与n互质的数的和sum=n*euler(n)/2 如果gcd(n,i)=1,那么必有gcd(n,n-i)=1,所以与n互质的数应该是成对出现的,每一对的和就是n,所以总和就是n*euler(n)/2;容斥原理解法 1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 #define N 1000010 5 using namespace std; 阅读全文
posted @ 2012-10-28 21:22 silver__bullet 阅读(265) 评论(0) 推荐(0)
摘要:A. 排序,把h,m都相同的归为一类,找到最多的 A 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define N 100010 6 using namespace std; 7 struct H{ 8 int h,m; 9 }s[N];10 int hash[N];11 bool cmp(H a,H b){12 if(a.h!=b.h)return a.h<b.h;13 return a.m<b.m;14 }15 阅读全文
posted @ 2012-10-26 06:58 silver__bullet 阅读(240) 评论(0) 推荐(0)
摘要:分析:中国剩余定理的求解,其中a[i]与a[j]不一定互质。 对于非互质版的中国剩余定理可以通过迭代的办法来求。 对于最终的通解 ans=At+B,我们可以通过逐一合并两个方程来更新A B,最后来得到答案。 最初A=a[1],B=b[1];然后将A B 带入下一个方程得到(At+B)mod a[i]==b[i]..得到一个特解tt,然后在求出此方程通解,再带回到ans中更新A B... 依次类推。。。。 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algo 阅读全文
posted @ 2012-10-24 17:10 silver__bullet 阅读(397) 评论(0) 推荐(0)
摘要:题目描述: 给定n个物品及m钱,对于每个物品有三个属性,价格p,价值v,q,如果手中的钱不足q,即使能够买得起这个物品,也不能交易,求最后能买到的物品最大价值。分析: 带限制的01背包。最容易想到的就是要按某种方式进行排序,可以先想两个问题。 1.为什么普通的01背包可以不用排序? 因为在普通的01背包问题当中每个物品是相对独立的,也就是说取得全局最优解与物品的放入顺序无关,所以不必排序就可以直接进行dp,而在这个问题中却并非如此,由于q的存在,当某一物品放入后可能就会对后面的物品造成影响,举个例子,比如背包容量为8,有两个物品,p1=5,q1=6,v1=1,p2=2,q2=4... 阅读全文
posted @ 2012-10-24 13:39 silver__bullet 阅读(300) 评论(1) 推荐(1)
摘要:分析:因为要洗完所有同种颜色的才能洗下一种颜色,所以先按颜色排序,对每种颜色做一次01背包。取两个最少时间的最大值,累加 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #include<string> 6 #include<iostream> 7 #define N 1100 8 using namespace std; 9 int dp[N][N],w[N][N],cnt[N],sum[N];10 int ma 阅读全文
posted @ 2012-10-22 21:10 silver__bullet 阅读(165) 评论(0) 推荐(0)
摘要:01背包统计第k优解,多开一维的数组,用来记录第几优解,然后每次更新的时候合并一下。。。 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #define N 1100 5 #define K 100 6 using namespace std; 7 int dp[N][K],w[N],v[N],s[N]; 8 bool cmp(int a,int b){ 9 return a>b;10 }11 int main(){12 int n,m,k,T;13 cin>> 阅读全文
posted @ 2012-10-22 13:02 silver__bullet 阅读(172) 评论(0) 推荐(0)
摘要:靠手速拿了个还可以的rank。。。不会dp依旧硬伤A.....A 1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 int hash[100]; 6 int main(){ 7 string s; 8 while(cin>>s){ 9 int cnt=0;10 memset(hash,0,sizeof(hash));11 for(int i=0;i<s.size();i++){12 if(... 阅读全文
posted @ 2012-10-21 21:25 silver__bullet 阅读(229) 评论(0) 推荐(0)
摘要:题目描述:...分析:因为不同年份之间没有什么互相影响,所以可用完全背包求解,唯一不同的就是每年的背包容量都在变大。 另外由于物品价钱都是1000的倍数,所以可以同时除以1000,减少内存。 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define N 100010 6 using namespace std; 7 int dp[N],w[N],v[N]; 8 int main(){ 9 int t;10 cin>& 阅读全文
posted @ 2012-10-20 22:00 silver__bullet 阅读(120) 评论(0) 推荐(0)
摘要:题目描述; 给定几种钱的面值,问用这些钱凑出n的价值有多少中方案。分析:背包问题,统计填满背包的方案数。 dp [ i ] [ j ]表示用前j种面值凑出i钱的方案数。 dp [ i ] [ j ]=sum { dp [ i - k*s [ j ] ] [ j-1 ] } 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #define N 7500 5 using namespace std; 6 typedef long long ll; 7 ll dp[N][5]; 8 i 阅读全文
posted @ 2012-10-20 21:44 silver__bullet 阅读(184) 评论(0) 推荐(0)
摘要:题目描述:...分析:因为只要剩余金额大于5肯定会支付成功,那么最优的办法肯定是要用最后的钱去买最贵的。只需要对除了最贵的物品之外的物品进行背包就可以。其中背包的容量是原来的减5 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #define N 1010 5 using namespace std; 6 int dp[N],w[N]; 7 int main(){ 8 int n,m; 9 while(cin>>n){10 if(!n)return 0;11 for 阅读全文
posted @ 2012-10-20 21:23 silver__bullet 阅读(129) 评论(0) 推荐(0)
摘要:题目描述: 给定连续的内存块,支持4个操作: 1.申请连续长为x的空间,并且返回这段区间的左端点。 2.释放包含x的内存块。 3.询问从左到右第x块的区间范围。 4.重置。分析: 和poj3667比较像,只是多了3 4的操作。 我开了两个线段树,第一个成段更新,为了记录每一段的颜色(其实就是第几次申请时被占用的),第二个记录每一段起点,这是为了方便操作3的查询。 最后reset的时候传一个懒惰标记就行。。重新build会超时 p.s.数组大小随便开的。。。其实可以小点。。无视就好 1 #include<iostream> 2 #include<cstdio... 阅读全文
posted @ 2012-10-19 07:50 silver__bullet 阅读(272) 评论(0) 推荐(0)
摘要:题目描述:给定连续的n个村庄,有三种操作: 1.D x:毁掉第x个村庄; 2.Q x:询问直接或间接与x相连的村庄数目 3.R :恢复上一个被毁掉的村庄。分析:用线段树维护区间内以左端点开始的连续区间,以右端点结束的连续区间。 询问我拆成了两部分,一个是询问x向右(含x)的连续区间长,一个是询问x向左(含x)的连续区间长,加和减一就是答案。 操作三用个栈记录下就行。 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #defin. 阅读全文
posted @ 2012-10-16 12:43 silver__bullet 阅读(225) 评论(0) 推荐(0)
摘要:HEU ACMer,11级,若菜一枚,无OI基础,喜欢数学。 刚从regional被暴回来,决定从零开始,于是就开了这个博客。大概应该会用到明年regional吧,我会用心经营的。 希望能在ACM这个圈子里结识很多朋友,希望能找到志同道合,实力差不多的朋友一起交流,共同进步。 QQ: 1029009341 Email:nopainnofame@sina.com 真心欢迎与各位互相交流。 阅读全文
posted @ 2012-10-15 20:48 silver__bullet 阅读(173) 评论(0) 推荐(0)
摘要:题意 求1到之间所有与n互质的数的四次幂之和。分析 分解n^5-(n-1)^5..可以求出1^4+2^4+...+n^4的公式S(n)=1/30*(n^5+15*n^2*(n+1)^2-10*n*(n+1)*(2*n+1)+15*n*(n+1)-6*n) 先求出S(n),利用容斥原理去掉是n的质因子的倍数的数的四次幂之和。。。 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #define N 100100 6 #include 阅读全文
posted @ 2012-10-11 23:15 silver__bullet 阅读(114) 评论(0) 推荐(0)
摘要:分析 模拟一个伸展树的操作,最后中序遍历一下就可以。。 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define N 1000010 6 #pragma comment(linker, "/STACK:102400000,102400000") 7 using namespace std; 8 int ch[N][2],pre[N],s[N],sz[N],num[N]; 9 bool rev[N]; 1 阅读全文
posted @ 2012-10-09 11:00 silver__bullet 阅读(155) 评论(0) 推荐(0)
摘要:题目描述 给定一个序列,询问某段区间内小于等于k的数的个数。分析 划分树+二分,二分的同时统计满足题意的数的个数。。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 100100 5 #define lson l,m,n<<1 6 #define rson m+1,r,n<<1|1 7 using namespace std; 8 int sorted[N],ans[N][20],num[N][20]; 9 void build(int 阅读全文
posted @ 2012-10-08 19:42 silver__bullet 阅读(135) 评论(0) 推荐(0)