随笔分类 -  dp

摘要:斜率优化dp;推荐学习http://www.cnblogs.com/perseawe/archive/2012/05/12/bz1010.html看着别人的题解自己学着推,终于理解了#include#include#include#define ll long long#define maxn 50005using namespace std;int q[maxn],head=0,tail=0;ll f[maxn];ll g[maxn],s[maxn];ll dp[maxn];ll get_g(int k,int j,int c){ return dp[k]+(f[k]+c)*(f[k]... 阅读全文
posted @ 2013-12-02 14:58 Yours1103 阅读(189) 评论(0) 推荐(0)
摘要:dp,用优先队列存,上个节点节点覆盖下来的长度;不过还不是很明白; 1 #include 2 #include 3 #include 4 #define maxn 1005 5 #define inf 999999 6 using namespace std; 7 struct node 8 { 9 int id;10 int v;11 node(int id=0,int v=0):id(id),v(v){}12 bool operatort.v;15 }16 };17 priority_queueq1,q2;18 19 int f[maxn],a[ma... 阅读全文
posted @ 2013-11-15 19:08 Yours1103 阅读(316) 评论(0) 推荐(0)
摘要:知道是状态压缩,但是不会做;看题解学的;dp[i]表示现在状态是i,先手-后手的分数。 1 #include 2 #include 3 #include 4 using namespace std; 5 6 int b,g,n,s,a,co[20],dd[20]; 7 int map[25][20],dp[10)dp[i]=max(dp[i],cnt+dp[i^(1<<j)]);53 else dp[i]=max(dp[i],-dp[i^(1<<j)]);54 }55 }56 }57 ... 阅读全文
posted @ 2013-11-12 20:41 Yours1103 阅读(226) 评论(0) 推荐(0)
摘要:感觉像是一个数位dp,高位的1如果不选的话,前面低位的数都可以选;不然只能选择为1的数;代码: 1 #include 2 #include 3 #define maxn 100005 4 using namespace std; 5 char s[maxn]; 6 int sum[maxn],num[maxn],n,ans,all; 7 8 int main() 9 {10 cin>>n;11 for(int i=1;i>num[i],sum[i]+=sum[i-1]+num[i];13 cin>>s;14 for(int i=n-1;i>=0;i--)15 阅读全文
posted @ 2013-10-12 19:29 Yours1103 阅读(199) 评论(0) 推荐(0)
摘要:一道DP题;一共有三种砖,1*2,2*1,2*2,然后要你铺满整个n*2的地板,求不重复的铺法数;方法:首先计算了不考虑对称的情况,然后计算只考虑对称的情况;所以结果就是(不考虑对称数+只考虑对称数)/2;递推关系:dp[i] 表示左右各伸展 i 的对称情况。dp[i+1] += dp[i]//两边补上 1 x 2dp[i+2] += dp[i]*2//两边补上2x1 跟 2x2 兩种。然后只考虑对称的情况下有两种情况:n==奇数:中间有个1*2;n==偶数;中间有两个2*1;或者两个2*1或者一个2*2;代码: 1 #include 2 #include 3 using namespace 阅读全文
posted @ 2013-10-10 17:11 Yours1103 阅读(136) 评论(0) 推荐(0)
摘要:动态规划;白书上的题,看了好久看不懂刘汝佳的解法;在网上无意中看到了大神的思路,比较好理解,膜拜!他的思路是这样的:设d[i]是n个数按顺时针方向分别从0开始编号,第一次删除0,以后每k个数删除一个,最后剩下的数。实际上d[i]就是顺时针偏移了多少位。状态转移方程:d[i] = (k - 1 + d[i-1]) % (n-1) + 1;(删了0后,剩下1,2,...,n,全部减1后得到0,1,2,...,n-1,所以原来该删k——>>k-1,顺时针偏移d[i-1]位,取模,加1后变回原来的编号)代码: 1 #include 2 #define maxn 10009 3 using 阅读全文
posted @ 2013-10-06 20:13 Yours1103 阅读(199) 评论(0) 推荐(0)
摘要:树形DP:要求找出树上距离为k的点的对数;对于每个节点,经过这个节点的符合条件的的点有两种:第一种:距离他为i的儿子和他爸爸中距离他爸爸为k-i-1;(不是符合的点对中的一个)第二种:他儿子中距离为其儿子为k-1的点;(此节点为符合条件的点对中的一个) 1 #include 2 #include 3 #define N 50009 4 using namespace std; 5 vectorvec[N]; 6 int dp[N][505]; 7 long long ans; 8 void dfs(int x,int f,int k) 9 {10 dp[x][0]=1;11 ... 阅读全文
posted @ 2013-10-06 19:14 Yours1103 阅读(192) 评论(0) 推荐(0)
摘要:三维DP 第K字典序从左向右找 根据dp数组的值算出每一位该打印什么代码: 1 #include 2 #include 3 using namespace std; 4 long long memo[9][221][221]; 5 long long solve(int n, int m, int last)//n划分成m个数最小值为last; 6 { 7 if(n==0) 8 { 9 if(m>=last) return 1;10 return 0;11 }12 long long &ret = memo[n][m][las... 阅读全文
posted @ 2013-10-06 18:36 Yours1103 阅读(146) 评论(0) 推荐(0)
摘要:一个简单的货郎担问题,用状态压缩dp可以解决;解法:d(i,S)=min{d(j,S-{j})+dis(i,j) | j belongs to S};边界条件:d(i,{})=dis(0,i).最终答案:d(0,{1,2,3```n-1})时间复杂度:O(n^2*2^b);代码: 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 int dp[1024][11],dis[11][11],posx[11],posy[11]; 7 8 int main() 9 {10 int t,x,y,n;11 ... 阅读全文
posted @ 2013-10-06 13:51 Yours1103 阅读(206) 评论(0) 推荐(0)
摘要:一个01背包问题;刚刚开始把题目看错了,以为物品的数目是有限的,然后让你求一个家庭里最多能够拿多个价值的东西;这样一来的话,这个题目就有点意思了;但是后来发现竟然是个简单的01背包问题 = =;代码: 1 #include 2 #define maxn 1007 3 #include 4 #include 5 using namespace std; 6 7 int price[maxn],weight[maxn],f[105]; 8 int main() 9 {10 int t,n,g,x;11 scanf("%d",&t);12 while(t--)13 ... 阅读全文
posted @ 2013-10-06 10:50 Yours1103 阅读(159) 评论(0) 推荐(0)
摘要:简单的博弈题,用dp解;每个人只能拿1,l,k个硬币;dp[i][j]表示第j个人拿是否能拿第i枚硬币;代码: 1 #include 2 #define maxn 1000007 3 using namespace std; 4 bool dp[maxn][2]; 5 int x,l,m,k; 6 7 int main() 8 { 9 scanf("%d%d%d",&k,&l,&m);10 for(int i=1;i=l)dp[i][j]|=1-dp[i-l][j^1];15 if(i>=k)dp[i][j]|=1-dp[i-k][j^1];1 阅读全文
posted @ 2013-10-06 10:14 Yours1103 阅读(142) 评论(0) 推荐(0)
摘要:简单的动态规划题,不过题目意思很蛋疼;刚刚开始认为是最长上升子序列,错的一塌糊涂;后来看了斌牛的题解才知道是最长公共子序列;题解:当a[i]==b[j],d(i,j)=(i-1,j-1)+1;else d(i,j)=max(d(i,j-1),d(i-1,j));代码: 1 #include 2 #define maxn 25 3 #include 4 #include 5 using namespace std; 6 int a[maxn],b[maxn],f[maxn][maxn]; 7 int main() 8 { 9 int n,x;10 scanf("%d",&am 阅读全文
posted @ 2013-10-04 23:07 Yours1103 阅读(176) 评论(0) 推荐(0)
摘要:Description 殷犇有很多队员。他们都认为自己是最强的,于是,一场比赛开始了~ 于是安叔主办了一场比赛,比赛有n个题目,每个题目都有一个价值Pi和相对能力消耗Wi,但是有些题目因为太坑不能同时做出来,并且坑题具有传递性。(a和b一起做会坑、b和c会坑则a和c也会坑) ACM队员们想知道,于是他们想知道在能力范围内,它们最多可以作出多少价值的题目。 聪明的你,告诉我,能帮帮他们吗?Input 第1行两个整数,n,Wmax,k(0 2 #include 3 #include 4 #define maxn 1005 5 using namespace std; 6 7 int f[max.. 阅读全文
posted @ 2013-10-04 13:22 Yours1103 阅读(222) 评论(0) 推荐(0)
摘要:一道dp题,虽然知道是dp,但是不会做;学习了ACM_cxlove大神的代码,终于明白了;搬运工:dp[i][j][k]表示 前i个已经完全匹配,而这时候,第i+1个已经加了j位,第i+2位已经加了k转移分为两步,枚举加,枚举减;上面是大神的原话,不过看了好久的代码才明白;下面是我的一点领悟: 1 #include 2 #include 3 #include 4 #define inf 1<<20 5 #define N 1005 6 using namespace std; 7 char s1[N],s2[N]; 8 int dp[N][10][10]; 9 int main() 阅读全文
posted @ 2013-09-25 17:03 Yours1103 阅读(196) 评论(0) 推荐(0)
摘要:树形dp;思想: 把正向边赋值为0;反向边赋值为1;然后求出点到其他点的最小距离;两次dfs:第一次是从下往上:记录每个点到所有子树中需要改变的边的条数;第二次是自上往下:由父节点求子节点到所有点的需要改变的边的条数。代码: 1 #include 2 #include 3 #include 4 #define maxn 200005 5 using namespace std; 6 7 struct node 8 { 9 int v,w;10 };11 12 vectorve[maxn];13 int dp[maxn],res;14 bool vis[maxn];15 16 void... 阅读全文
posted @ 2013-09-17 17:21 Yours1103 阅读(540) 评论(0) 推荐(0)
摘要:树形dp题,要求求出书上的最远距离;很经典的一种树形dp;思路:最远距离要么是从老爸的最远距离+自己与老爸的距离; 要么是儿子的最远距离+自己与儿子的距离;然后比较上面两个的大小就是答案了!参考了别人的代码:两次搜索:1.第一次搜索是从下至上的搜索,找到每个节点的最远距离f[],次远距离sf[];并记录最远距离的那个点;2.第二次搜索是从上往下的搜索,找到老爸那边来的最远距离dp[];代码: 1 #include 2 #include 3 #include 4 #define maxn 10005 5 using namespace std; 6 7 struct node 8... 阅读全文
posted @ 2013-09-17 16:11 Yours1103 阅读(204) 评论(0) 推荐(0)
摘要:树形dp的基础题;状态转移很简单:老爸没选,儿子可选可不选,最大就行;老爸选了,儿子肯定不能选;dp[root][0]+=max(dp[son][1],dp[son][0]); dp[root][1]+=dp[son][0];代码: 1 #include 2 #include 3 #include 4 #define maxn 6003 5 using namespace std; 6 7 int w[maxn],dp[maxn][2]; 8 vectorve[maxn]; 9 bool vis[maxn];10 11 void dfs(int a)12 {13 vis... 阅读全文
posted @ 2013-09-17 09:09 Yours1103 阅读(203) 评论(0) 推荐(0)
摘要:一个树形dp的题,又是一个涉及不深的领域 = =;不过在网上看到了大神用很巧的思路解决了这个题;大神的思路就是:从树的底部往上看:如果一棵子树拥有两个及以上的叶子节点,可以将这棵子树与大树分离,并且将子树化成一条直线;为什么这样子是最优呢?我不会证明,但我觉得这种情况可以保留最多不被删除的边;代码: 1 #pragma comment(linker,"/STACK:1024000000,1024000000") 2 #include 3 #include 4 #include 5 #include 6 #define maxn 1000005 7 using namespa 阅读全文
posted @ 2013-09-16 15:02 Yours1103 阅读(228) 评论(0) 推荐(0)
摘要:数位dp题;也是我做的第一个数位dp的题目;感觉数位dp的模板性很强啊,思想都差不太多!有几个写的很好的参考资料:推荐一下:数位计数问题解法研究浅谈数位类统计问题我的代码: 1 #include 2 #include 3 #define maxn 16 4 #define ll long long 5 using namespace std; 6 7 int dp[maxn][5000]; 8 int d[maxn],sum; 9 10 ll dfs(int w,int he,bool flag)11 {12 if(he<0)return 0;13 if(!w)return ... 阅读全文
posted @ 2013-09-16 14:00 Yours1103 阅读(219) 评论(0) 推荐(0)