专章dp入门 1.1
Posted noble_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了专章dp入门 1.1相关的知识,希望对你有一定的参考价值。
下述题目都为基础的dp包括、经典问题,乃dp入门必备之题。
注意: 1、从最下面往上刷
--------------------------------------------
洛谷P1280 尼克的任务
逆序dp,详见注释
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int dp[10005],sum[10005];//dp[i]:i-n的最大空闲时间 5 struct task{ 6 int begin,last;//开始 持续 7 }a[10005]; 8 bool cmp(task a,task b) 9 { 10 return a.begin>b.begin;//千万要从大到小排!! 11 } 12 int main() 13 { 14 int n,k,num=1;//num记数 15 scanf("%d%d",&n,&k); 16 for(int i=1;i<=k;i++) 17 { 18 scanf("%d%d",&a[i].begin,&a[i].last); 19 sum[a[i].begin]++; 20 } 21 sort(a+1,a+1+k,cmp); 22 for(int i=n;i>=1;i--) 23 { 24 if(sum[i]==0) dp[i]=dp[i+1]+1; //即目前状态空闲 25 else 26 { 27 for(int j=1;j<=sum[i];j++) 28 dp[i]=max(dp[i+a[num++].last],dp[i]); 29 } 30 } 31 printf("%d",dp[1]); 32 return 0; 33 }
洛谷P1091 合唱队形
从头开始,从尾开始各跑一次LIS
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int dp[105],dp2[105],a[105]; 6 int main() 7 { 8 int n,maxnum=99999999,k=0; 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 11 for(int i=1;i<=n;i++) 12 { 13 dp[i]=1; 14 for(int j=0;j<i;j++) 15 { 16 if(a[i]>a[j]) dp[i]=max(dp[j]+1,dp[i]); 17 } 18 } 19 for(int i=n;i>=1;i--) 20 { 21 dp2[i]=1; 22 for(int j=n;j>=i;j--) 23 { 24 if(a[i]>a[j]) dp2[i]=max(dp2[j]+1,dp2[i]); 25 } 26 } 27 for(int i=1;i<=n;i++) 28 { 29 // printf("%d:%d %d \n",i,dp[i],dp2[i]); 30 maxnum=min(maxnum,n-(dp[i]+dp2[i]-1)); 31 /// if(maxnum==n-(dp[i]+dp2[i]-1)) k=i; 32 } 33 printf("%d",maxnum); 34 return 0; 35 }
洛谷P1115 最大子段和 dp
#include <cstdio> #include <algorithm> using namespace std; int dp[200005],a[200005]; int main() { int n,ans=-100000000; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); dp[0]=a[0]; for(int i=1;i<n;i++) { dp[i]=max(dp[i-1],0)+a[i]; ans=max(ans,dp[i]); } printf("%d",ans); return 0; }
洛谷P1508 Likecloud-吃、吃、吃
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 typedef long long ll; 5 ll dp[205][205]; 6 ll Max(ll a,ll b,ll c) 7 { 8 return max(max(a,b),c); 9 } 10 int main() 11 { 12 ll n,m; 13 scanf("%lld%lld",&m,&n); 14 for(ll i=1;i<=m;i++) 15 for(ll j=1;j<=n;j++) scanf("%lld",&dp[i][j]); 16 for(int i=1;i<=m+1;i++) 17 { 18 for(int j=1;j<=n;j++) 19 { 20 dp[i+1][j]+=Max(dp[i][j-1],dp[i][j],dp[i][j+1]); 21 } 22 } 23 printf("%lld",Max(dp[m][(n+1)/2],dp[m][(n+1)/2+1],dp[m][(n+1)/2-1])); 24 }
洛谷P1510 精卫填海
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int dp[10005],v,n,c,m[10005],k[10005]; 5 int main() 6 { 7 scanf("%d%d%d",&v,&n,&c); 8 for(int i=0;i<n;i++) 9 scanf("%d%d",&k[i],&m[i]); 10 for(int i=0;i<n;i++) 11 { 12 for(int j=c;j>=m[i];j--) 13 { 14 dp[j]=max(dp[j],dp[j-m[i]]+k[i]); 15 } 16 } 17 for(int j=0;j<=c;j++) 18 { 19 if(dp[j]>=v) 20 { 21 printf("%d",c-j); 22 return 0; 23 } 24 } 25 printf("Impossible"); 26 return 0; 27 }
洛谷P1855 榨取kkksc03
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int dp[205][205],mi[205],ti[205]; 5 int main() 6 { 7 int n,m,t; 8 scanf("%d%d%d",&n,&m,&t); 9 for(int i=0;i<n;i++) 10 { 11 scanf("%d%d",&mi[i],&ti[i]); 12 } 13 for(int i=0;i<n;i++) 14 { 15 for(int j=m;j>=mi[i];j--)//for(int j=mi[i];j<=m;j++) 16 { 17 for(int k=t;k>=ti[i];k--)//for(int k=ti[i];k<=t;k++) 18 { 19 dp[j][k]=max(dp[j][k],dp[j-mi[i]][k-ti[i]]+1); 20 } 21 } 22 } 23 printf("%d",dp[m][t]); 24 return 0; 25 }
洛谷P1216 [USACO1.5]数字三角形 Number Triangles
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int tr[1002][1002]; 5 int main() 6 { 7 int n; 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++) 10 { 11 for(int j=1;j<=i;j++) 12 scanf("%d",&tr[i][j]); 13 } 14 for(int i=n-1;i>=1;i--) 15 { 16 for(int j=1;j<=i;j++) 17 { 18 tr[i][j]+=max(tr[i+1][j],tr[i+1][j+1]); 19 } 20 } 21 printf("%d",tr[1][1]); 22 return 0; 23 }
洛谷P1910 L国的战斗之间谍
1 #include<cstring> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 using namespace std; 6 int n,m,x; 7 int a[1200],b[1200],c[1200],dp[1200][1200]; 8 int main() 9 { 10 scanf("%d%d%d",&n,&m,&x); 11 for(int i=0;i<n;i++) 12 scanf("%d%d%d",&a[i],&b[i],&c[i]); 13 for(int i=0;i<n;i++) 14 { 15 for(int j=m;j>=b[i];j--) 16 { 17 for(int k=x;k>=c[i];k--) 18 { 19 dp[j][k]=max(dp[j][k],dp[j-b[i]][k-c[i]]+a[i]); 20 } 21 } 22 } 23 printf("%d",dp[m][x]); 24 return 0; 25 }
洛谷P2925 [USACO08DEC]干草出售Hay For Sale
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 int c[5004],f[50004]; 5 int main(){ 6 int V,n; 7 cin>>V>>n; 8 for(int i=1;i<=n;i++) scanf("%d",&c[i]); 9 for(int i=1;i<=n;i++){ 10 for(int v=V;v>=c[i];v--){ 11 f[v]=max(f[v],f[v-c[i]]+c[i]); 12 } 13 if(f[V]==V) {cout<<V<<endl;return 0;} 14 } 15 printf("%d",min(f[V],V)); 16 return 0; 17 }
洛谷P2347 砝码称重
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int dp[1005],a[10],sum=0; 5 int main() 6 { 7 for(int i=0;i<6;i++) scanf("%d",&a[i]); 8 for(int i=0;i<=a[0];i++) 9 for(int b=0;b<=a[1];b++) 10 for(int c=0;c<=a[2];c++) 11 for(int d=0;d<=a[3];d++) 12 for(int e=0;e<=a[4];e++) 13 for(int f=0;f<=a[5];f++) 14 { 15 dp[i+2*b+3*c+5*d+10*e+20*f]=1; 16 } 17 for(int i=1;i<1003;i++) 18 { 19 if(dp[i]==1) sum++; 20 } 21 printf("Total=%d",sum); 22 return 0; 23 }
洛谷P2722 总分 Score Inflation
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 int dp[10005],m,n,w[10005],v[10005]; 5 int main() 6 { 7 scanf("%d%d",&m,&n); 8 for(int i=0;i<n;i++) 9 scanf("%d%d",&v[i],&w[i]); 10 for(int i=0;i<n;i++) 11 { 12 for(int j=w[i];j<=m;j++) 13 { 14 dp[j]=max(dp[j],dp[j-w[i]]+v[i]); 15 } 16 } 17 printf("%d",dp[m]); 18 return 0; 19 }
以上是关于专章dp入门 1.1的主要内容,如果未能解决你的问题,请参考以下文章