【专题】 动态规划

递推类

hdu 2084 数塔 简单从上往下递推

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define rg register
10 #define ll long long
11 const int N=100+5;
12 int n,ans=0,f[N][N],mp[N][N];
13 template<class t>void rd(t &x)
14 {
15     x=0;int w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     x=w?-x:x;
19 }
20 
21 int main()
22 {
23     int T;rd(T);
24     while(T--)
25     {
26         ans=0;
27         memset(f,0,sizeof(f));
28         memset(mp,-1,sizeof(mp));
29         rd(n);
30         for(rg int i=1;i<=n;++i)
31         for(rg int j=1;j<=i;++j) rd(mp[i][j]);
32         f[1][1]=mp[1][1];
33         for(rg int i=2;i<=n;++i)
34         for(rg int j=1;j<=i;++j)
35         f[i][j]=max(f[i][j],max(f[i-1][j]+mp[i][j],f[i-1][j-1]+mp[i][j]));
36         for(rg int i=1;i<=n;++i) ans=max(ans,f[n][i]);
37         printf("%d\n",ans);
38     }
39     return 0;
40 }
hdu 2084 数塔

hdu 2018 母牛的故事 简单递推计数 和斐波那契差不多emmm

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define rg register
10 #define ll long long
11 const int N=60;
12 int n,f[N];
13 template<class t>void rd(t &x)
14 {
15     x=0;int w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     x=w?-x:x;
19 }
20 
21 int main()
22 {
23     f[1]=1,f[2]=2,f[3]=3;
24     for(rg int i=4;i<=55;++i) f[i]=f[i-3]+f[i-1];
25     while(scanf("%d",&n)==1&&n)
26     {
27         printf("%d\n",f[n]);
28     }
29     return 0;
30 }
hdu 2018 母牛的故事

hdu 2044 一只小蜜蜂... 同上 要记得开long long QAQ

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define rg register
10 #define ll long long
11 const int N=60;
12 ll n,f[100],a,b;
13 template<class t>void rd(t &x)
14 {
15     x=0;int w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     x=w?-x:x;
19 }
20 
21 int main()
22 {
23     memset(f,0,sizeof(f));
24     f[1]=1;
25     for(ll i=2;i<=60;++i) f[i]=f[i-1]+f[i-2];
26     rd(n);
27     for(ll i=1;i<=n;++i)
28     {
29         rd(a),rd(b);
30         printf("%lld\n",f[b-a+1]);
31     }
32     
33     return 0;
34 }
hdu 2044 一只小蜜蜂

 CodeForces - 429B Working out  

大意:有小A和小B 小A从[1,1]出发到[n,m] 小B从[n,1]出发到[1,m] 两个人必须在达各自终点前相遇一次,并且相遇那个点的值不能取 求这样子走完后小A和小B共同获得的最大价值

看翻译的时候不小心看到了思路 哭泣QAQ

先算出从四个点出发到各个点的最大价值 然后枚举可能相遇的点 因为要在达各自终点前相遇一次所以相遇点的i和j要从2开始枚举(QAQ没考虑到这个到test23就挂了)

相遇时只有这两种可能(丑陋的图)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define rg register
10 #define ll long long
11 const int N=1005;
12 int n,m,ans=0,f[5][N][N],mp[N][N];
13 template<class t>void rd(t &x)
14 {
15     x=0;int w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     x=w?-x:x;
19 }
20 
21 int main()
22 {
23     memset(f,0,sizeof(f));
24     rd(n),rd(m);
25     for(rg int i=1;i<=n;++i)
26     for(rg int j=1;j<=m;++j) rd(mp[i][j]);
27     for(rg int i=1;i<=n;++i)
28     {
29         for(rg int j=1;j<=m;++j)
30         f[1][i][j]=max(f[1][i][j],max(f[1][i-1][j],f[1][i][j-1])+mp[i][j]);//[1,1]-[n,m]
31         for(rg int j=m;j>=1;--j)
32         f[2][i][j]=max(f[2][i][j],max(f[2][i-1][j],f[2][i][j+1])+mp[i][j]);//[1,m]-[n,1]
33     }
34     for(rg int i=n;i>=1;--i)
35     {
36         for(rg int j=1;j<=m;++j)
37         f[3][i][j]=max(f[3][i][j],max(f[3][i+1][j],f[3][i][j-1])+mp[i][j]);//[n,1]-[1,m]
38         for(rg int j=m;j>=1;--j)
39         f[4][i][j]=max(f[4][i][j],max(f[4][i+1][j],f[4][i][j+1])+mp[i][j]);//[n,m]-[1,1]
40     }
41     for(rg int i=2;i<n;++i)
42     for(rg int j=2;j<m;++j)
43     ans=max(ans,max(f[1][i-1][j]+f[4][i+1][j]+f[2][i][j+1]+f[3][i][j-1],f[3][i+1][j]+f[2][i-1][j]+f[4][i][j+1]+f[1][i][j-1]));
44     printf("%d",ans);
45     return 0;
46 }
CF429B Working out

【UVa 10328】Coin Toss [动态规划 递推][高精度

树形dp

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1500+5;
 4 
 5 int n,f[N][2];
 6 int cnt=0,head[N<<1];
 7 int read()
 8 {
 9     int x=0,w=0;char ch=0;
10     while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
11     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
12     return w?-x:x;
13 }
14 struct edge
15 {
16     int v,nxt;
17 }e[N<<1];
18 void add(int u,int v)
19 {
20     e[++cnt].v=v;
21     e[cnt].nxt=head[u];
22     head[u]=cnt;
23 }
24 
25 void dp(int u,int fa)
26 {
27     f[u][0]=0,f[u][1]=1;
28     for(int i=head[u];i!=0;i=e[i].nxt)
29     {
30         int v=e[i].v;
31         if(v==fa) continue;
32         dp(v,u);
33         f[u][0]+=f[v][1];
34         f[u][1]+=min(f[v][0],f[v][1]);
35     }
36 }
37 
38 int main()
39 {
40     while(scanf("%d",&n)!=EOF)
41     {
42         memset(head,0,sizeof(head));cnt=0; 
43         for(int i=0;i<n;i++)
44         {
45             int x,k;
46             scanf("%d:(%d)",&x,&k);
47             for(int j=0;j<k;j++)
48             {
49                 int a=read();
50                 add(x,a);add(a,x);
51             }
52         }
53         dp(0,-1);
54         printf("%d\n",min(f[0][0],f[0][1]));
55     }
56     return 0;
57 }
士兵守卫 树形dp
没有上司的舞会 树形dp

 longest 求树的直径

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1005;
 4 const int inf=0x3f3f3f;
 5 int n,f[N][2],ans=0;
 6 int cnt=0,head[N<<1];
 7 int read()
 8 {
 9     int x=0,w=0;char ch=0;
10     while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
11     while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
12     return w?-x:x;
13 }
14 struct edge
15 {
16     int v,nxt,w;
17 }e[N];
18 void add(int u,int v,int w)
19 {
20     e[++cnt].v=v;
21     e[cnt].w=w;
22     e[cnt].nxt=head[u];
23     head[u]=cnt;
24 }
25 
26 void dp(int u,int fa)
27 {
28     f[u][1]=0,f[u][2]=0;
29     for(int i=head[u];i;i=e[i].nxt)
30     {
31         int w=e[i].w,v=e[i].v;
32         if(v==fa) continue;
33         dp(v,u);//搜儿子
34         int dis=f[v][1]+w;
35         if(dis>f[u][1])
36         {
37             f[u][2]=f[u][1];
38             f[u][1]=dis;
39         }
40         else if(dis>f[u][2])
41         {
42             f[u][2]=dis;
43         }
44         ans=max(ans,f[u][1]+f[u][2]);
45     }
46 }
47 
48 int main()
49 {
50     memset(head,0,sizeof(head));
51     n=read();
52     for(int i=1;i<n;i++)
53     {
54         int u=read(),v=read(),w=read();
55         add(u,v,w);add(v,u,w);
56     }
57     dp(1,0);
58     printf("%d",ans);
59     return 0;
60 }
longest 树形dp

 

posted @ 2019-04-26 11:02  委屈的咸鱼鱼鱼鱼  阅读(125)  评论(0编辑  收藏  举报