08 2013 档案

摘要:状态压缩DP,被字典序坑了10几分钟。。。。。。。#include #include using namespace std; const int INF=10; j-=j&(-j)) { tmp=j&(-j); xx=p[tmp]; if(dp[i^tmp].alt+sub[xx].t>sub[xx].ed) now=dp[i^tmp].alt+sub[xx].t-sub[xx].ed; else no... 阅读全文
posted @ 2013-08-29 13:11 Ink_syk 阅读(148) 评论(0) 推荐(0)
摘要:DP,比较容易想到是2维DP,表示到第一个字符串的i和第二个字符串的j最大值是多少, 字符串下标的0在这里对应的i,j是1#include #include #include #include using namespace std; const int INF=-(1<<29); char s1[105], s2[105]; int dist[151][151], dp[105][105]; void init() { dist['A']['A']=5; dist['A']['C']=dist['C' 阅读全文
posted @ 2013-08-28 09:42 Ink_syk 阅读(125) 评论(0) 推荐(0)
摘要:DP大水题。。关键是路径记录#include #include #include using namespace std; const int INF=11) puts(""); memset(vis,0,sizeof(vis)); memset(can,0,sizeof(can)); memset(path,-1,sizeof(path)); scanf("%d",&n); for(i=1;i=0) dp[i]=maxv+in[i]; } ans=-... 阅读全文
posted @ 2013-08-27 15:33 Ink_syk 阅读(135) 评论(0) 推荐(0)
摘要:第二道状态压缩。。。 自己做出来还是很爽的二维, 第一维表示当前状态, 第二维表示当前地点。先从未达到tt这个点的状态推出当前有tt状态的点,然后再根据同状态其他已到达点 试着从其他点更新到该点,使得时间更小。#include #include #include using namespace std; int map[12][12], dp[1333][11], p[12]; const int INF=10; j-=j&(-j)) { tt=j&(-j); for(r=0; r<=n; r++) ... 阅读全文
posted @ 2013-08-27 13:40 Ink_syk 阅读(114) 评论(0) 推荐(0)
摘要:第一道状态压缩DP。。。。入门题 按照自己的思路来 AC了先把每行可行的状态求出来 再进行DP#include #include #include using namespace std; const int mod=100000000; int dp[13][5000], map[13][13], state[13][1005], len[13]; int main() { int n, m, i, j, k; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<n;i++) for(j=0;... 阅读全文
posted @ 2013-08-27 11:56 Ink_syk 阅读(112) 评论(0) 推荐(0)
摘要:至少一种 至多一种 还有自由选取的背包问题参考别人的- -不说了#include #include #include #include using namespace std; int n, T, ans, dp1[105], dp2[105]; struct node { int m, tp; int t[105], h[105]; } set[105]; bool cmp(node x,node y) { return x.tp=set[i].t[j]; k--) { dp2[k]=max(dp... 阅读全文
posted @ 2013-08-24 09:57 Ink_syk 阅读(119) 评论(0) 推荐(0)
摘要:可以把每行看做是最多挑一个的物品系列,然后背包过。。#include #include #include #include using namespace std; int dp[105], v[105][105]; int main() { int n, m, i, j, k, w; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; memset(dp,-63,sizeof(dp)); dp[0]=0; for(i=0;i=0;j--) ... 阅读全文
posted @ 2013-08-24 09:43 Ink_syk 阅读(134) 评论(0) 推荐(0)
摘要:这题乍一看是01背包水题,其实一看数据,明显直接01背包是过不了的, 再看那个V-C的范围是0-10 很明显,可能的搭配数最多也就121种那么我就开一个数组记录下各种搭配的数量,用多重背包过#include #include #include #include using namespace std; int dp[10005]; char s[15]; int v, c, data[11][11], m; void deal(int vi,int w,int num) { int i, j, k; k=1; while(k=k*w;j--) ... 阅读全文
posted @ 2013-08-24 09:03 Ink_syk 阅读(86) 评论(0) 推荐(0)
摘要:最短路径+01背包。。#include#include#include#include#includeusing namespace std;const int INF=1=dis[i];j--) { dp[j]=max(dp[j],dp[j-dis[i]]+po[i]); } } int ans; bool f=false; for(i=0;isum/2) { ans=i; f=tr... 阅读全文
posted @ 2013-08-22 20:04 Ink_syk 阅读(144) 评论(0) 推荐(0)
摘要:难点在于用并查集求与根节点的距离并更新吧。。 遇到过好几次了#include#include#include#include#includeusing namespace std;int n, q, fa[10005], num[10005], cou[10005];void init(){ int i; for(i=1; i<=n; i++) fa[i]=i, num[i]=1, cou[i]=0;}int find(int x){ if(x==fa[x]) return x; int tmp=fa[x]; fa[x]=find(fa[x]); ... 阅读全文
posted @ 2013-08-22 19:55 Ink_syk 阅读(126) 评论(0) 推荐(0)
摘要:很有技巧的并查集 参考了别人的#include #include #include using namespace std; int high[30005], fa[30005], top[30005], ret[30005]; void init() { int i; for(i=0; i=0;i--) { high[ret[i]]+=high[fa[ret[i]]]; fa[ret[i]]=id; } return id; } int main() { int p, x, y, a, b; char o... 阅读全文
posted @ 2013-08-20 15:48 Ink_syk 阅读(152) 评论(0) 推荐(0)
摘要:并查集 过了#include #include #include using namespace std; bool pipe[][4]= {1,1,0,0, 0,1,1,0, 1,0,0,1, 0,0,1,1, 0,1,0,1, 1,0,1,0, 1,1,1,0, 1,1,0,1, 1,0,1,1, ... 阅读全文
posted @ 2013-08-20 15:43 Ink_syk 阅读(102) 评论(0) 推荐(0)
摘要:将Xiaoqian可付的钱的值用多重背包的方式计算拼凑起来所需的最小硬币数,用完全背包的方式计算找钱的值的拼凑最小硬币数。然后再寻找最小值。#include#include#include#includeusing namespace std;int dp1[20005], dp2[20005], t, v[105], r[105];const int INF=1=20000) { for(i=v[x];i=k*v[x];i--) dp1[i]=min(dp1[i],dp1[i-k*v[x]]+k); r[x]-=k; ... 阅读全文
posted @ 2013-08-19 19:06 Ink_syk 阅读(121) 评论(0) 推荐(0)
摘要:在完全背包的基础上再多一维就好了#include#include#include#includeusing namespace std;int v[105], r[105];int dp[105][105]; //忍耐度,杀怪数int main(){ int n, i, j, k, s, m, l; while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF) { memset(dp,0,sizeof(dp)); for(i=0;i=n) { ans=dp[i... 阅读全文
posted @ 2013-08-19 19:02 Ink_syk 阅读(147) 评论(0) 推荐(0)
摘要:意思是将物品尽量分成价值相近的两部分,那么就总价值除以2,然后就是多重背包的做法#include#include#include#includeusing namespace std;int v[55], r[55], m;bool dp[130000];void deal(int x){ int i; if(v[x]*r[x]>=m) { for(i=v[x];i=k*v[x];i--) if(dp[i-k*v[x]]) dp[i]=true; r[x]-=k; k*=2; ... 阅读全文
posted @ 2013-08-19 18:59 Ink_syk 阅读(115) 评论(0) 推荐(0)
摘要:多重背包模板题#include#include#include#includeusing namespace std;int n, dp[105];struct Dami{ int v, w, d;} ri[105];void deal(int x){ int i; if(ri[x].d*ri[x].v>=n) { for(i=ri[x].v;i=ri[x].v*k;i--) dp[i]=max(dp[i-ri[x].v*k]+ri[x].w*k,dp[i]); ri[x].d-=k; ... 阅读全文
posted @ 2013-08-19 18:55 Ink_syk 阅读(162) 评论(0) 推荐(0)
摘要:模拟题,,,,注意 15次操作限定要精准不要多一次也不要少一次。 找循环的时候从最近的找代码比较挫。。#include #include #include #include #include using namespace std; char s[88], ts[105], nt[105], cpy[17][105]; int vis[10], a[105]; int len, l1; void deal() { int i, j; for(i=0; i=0; j--) nt[l1++]=a[j]+'0'; nt[l1++... 阅读全文
posted @ 2013-08-18 16:34 Ink_syk 阅读(99) 评论(0) 推荐(0)
摘要:个人使用了离散+二分。。#include #include #include #include using namespace std; int a[4005], b[4005], c[4005], d[4005], sum1[16000005], sum2[16000005], bin[16000005], num[16000005], top; int find(int x,int l,int r) { int m; while(l>1; if(bin[m]==x) return m; if(bin[m]<x) ... 阅读全文
posted @ 2013-08-17 23:57 Ink_syk 阅读(102) 评论(0) 推荐(0)
摘要:简单大数加法,,,题意略蛋疼, 意思是说N行里每行两个数分别代表a的N-I位和b的N-i位的数字,将a和b相加 求值 只需要输出N位 就算最后进位到N+1位也不用输出#include #include #include using namespace std; char n1[1000005], n2[1000005], ans[1000005]; int main() { int n, i, j; char a, b; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) { ... 阅读全文
posted @ 2013-08-17 11:50 Ink_syk 阅读(120) 评论(0) 推荐(0)
摘要:好像是智力题的样子。。参考:http://www.cnblogs.com/drizzlecrj/archive/2007/10/20/931011.html以下是构造N个人(N >= 1)过桥最佳方案的方法:1)如果N=1或者N=2,所有人直接过桥。2)如果N=3,由最快的人往返一次把其他两人送过河。3)如果N>=4,设A,B为走的最快的和次快的旅行者,过桥所需时间分别为a,b;而Z,Y为走得最慢的和次慢的旅行者,过桥所需时间分别为z,y。那么当2b>a+y时,使用模式一将Z和Y移动过桥当2b #include #include #include #include #incl 阅读全文
posted @ 2013-08-16 20:53 Ink_syk 阅读(144) 评论(0) 推荐(0)
摘要:二维树状数组,注意树状数组下标不能从0开始, 且注意数据中 x1, y1 对于x2, y2不一定是左上角和右上角#include #include #include #include #include #include using namespace std; int bk[1005][1005]; int n=1004; int lowbit(int x) { return x&(-x); } int query(int x,int y) { int tp, ret=0; while(x>0) { tp=y; while(tp>... 阅读全文
posted @ 2013-08-16 15:52 Ink_syk 阅读(114) 评论(0) 推荐(0)
摘要:线段树区间变化, 用2进制保存颜色。。#include #include #include #include #include #include using namespace std; #define LL(x) (x>1; build(LL(p),l,m); build(RR(p),m+1,r); } void PushDown(int p) { if(T[p].col!=-1) { T[LL(p)].va=T[RR(p)].va=T[p].col; T[LL(p)].col=T[RR(p)].col=T[p].col; ... 阅读全文
posted @ 2013-08-16 13:23 Ink_syk 阅读(125) 评论(0) 推荐(0)
摘要:这题就是找到对应钥匙然后突破对应的门,反正最终目的是要到达X 这个终点。要求花费最小时间,如果不能到达输出The poor student is trapped!很明显是广搜,把钥匙的四种状态都加入到哈希表来记重,还有对应的坐标所以是六维数组。。#include #include #include #include #include #include using namespace std; int n, m; char map[105][105]; bool vis[105][105][2][2][2][2]; struct node { node(int p,int q,bool ... 阅读全文
posted @ 2013-08-16 09:36 Ink_syk 阅读(105) 评论(0) 推荐(0)
摘要:这题真的过的好艰辛啊,自己的方法是不对的,参考了某个大神的博客,然后修改自己的代码才通过。对于各个区间的交叉之类的还不是很会啊,尚需努力。。。。参考:大神博客线段树真的写的好挫啊,,,,,无力吐槽了。。。题意是对 一些气球染色,然后输出最长的且最近的那个染成白色的连续区间#include #include #include #include #include #include #include using namespace std; #define LL(x) x=r) return; T[p].l=l; T[p].r=r; T[p].va=-1; if(l=... 阅读全文
posted @ 2013-08-16 00:01 Ink_syk 阅读(105) 评论(0) 推荐(0)
摘要:四舍五入的思想方法,一直处理到只剩下整十,整百,整千。。。。。#include #include #include using namespace std; int main() { int n, a, i, j, ten, tmp; scanf("%d",&n); while(n--) { ten=1; scanf("%d",&a); while(a>10) { tmp=a%10; a/=10; if(tmp>=5) ... 阅读全文
posted @ 2013-08-15 20:39 Ink_syk 阅读(109) 评论(0) 推荐(0)
摘要:这道题是把题目给你的好像是递归的方式改变成 递推的方式, 只要预处理一下,答案就直接全部出来了#include #include #include using namespace std; int dp[22][22][22]; //w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1) int main() { int a, b, c, i, j, k; for(i=0;i20||b>20||c>20) a=b=c=20; printf("w(%d, %d, %... 阅读全文
posted @ 2013-08-15 20:33 Ink_syk 阅读(104) 评论(0) 推荐(0)
摘要:这道题目如果直接用4个for循环暴力求解显然是不行的 ,所以我用一个优化减少一个循环,又由于值是正负的,所以又可以从-100,100 变成只要循环1-100就足够#include #include #include #include #include using namespace std; bool vis[10005]; void init() { int i; memset(vis,0,sizeof(vis)); for(i=1;i0&&b>0&&c>0&&d>0)||(a0&&vis[xx]) ans+= 阅读全文
posted @ 2013-08-15 20:28 Ink_syk 阅读(149) 评论(0) 推荐(0)
摘要:#include #include #include #include using namespace std; int n, a[30005], c[30005], d[30005], k, vis[30005]; long long b[30005]; int find(int x) { int l=1, r=k-1; while(l>1; if(c[m]==x) return m; if(c[m]0) { ret+=b[p]; p-=lowbit(p); } return ret; }... 阅读全文
posted @ 2013-08-12 13:14 Ink_syk 阅读(128) 评论(0) 推荐(0)
摘要:#include #include #include #include #include #include using namespace std; char y[15], x[15]; struct Node { int va, l, r; } nod[2][15]; int r[2]; void build(int t,int k,int p) { if(t<nod[k][p].va) { if(nod[k][p].l==-1) { nod[k][r[k]].va=t; nod[k][r... 阅读全文
posted @ 2013-08-08 14:20 Ink_syk 阅读(119) 评论(0) 推荐(0)
摘要:#include #include #include #include #include #include using namespace std; bool f[1200]; int c[1100]; int main() { int i, j, m, n; while(scanf("%d",&n)!=EOF) { if(n==0) break; memset(f,0,sizeof(f)); for(i=0; i=55) f[j]=true; } } for(i=0... 阅读全文
posted @ 2013-08-05 18:53 Ink_syk 阅读(127) 评论(0) 推荐(0)
摘要:#include #include #include #include #include #include using namespace std; int n, m; char map[105][105]; bool vis[105][105][2][2][2][2]; struct node { node(int p,int q,bool a1,bool a2,bool a3,bool a4,int a5) { x=p, y=q, b=a1, ye=a2, r=a3, g=a4, now=a5; } node() {} int x, ... 阅读全文
posted @ 2013-08-04 12:09 Ink_syk 阅读(109) 评论(0) 推荐(0)
摘要:#include #include #include #include #include using namespace std; char map[22][22]; int sx, sy, ex, ey, n, m; int dx[]= {1,0,-1,0}, dy[]= {0,1,0,-1}; bool vis[22][22][22][22]; struct sta { sta(int a,int b,int c,int d,int e) { x1=a,y1=b,x2=c,y2=d,now=e; } sta() {}; int x1,... 阅读全文
posted @ 2013-08-03 21:25 Ink_syk 阅读(116) 评论(0) 推荐(0)