1. 程式人生 > >【專章】dp入門 1.1

【專章】dp入門 1.1

技術 ret hide pla -c -- ++ onclick font

下述題目都為基礎的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 }
View Code

洛谷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 }
View Code

洛谷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;
}
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

洛谷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 }
View Code

【專章】dp入門 1.1