zoukankan      html  css  js  c++  java
  • kuangbin带你飞dp专题-基础dp

    dp

    HDU - 1257 最少拦截系统

     最长递增子序列

     1 #include<iostream>
     2 using namespace std;
     3 const int maxn=1e7;
     4 int a[maxn],dp[maxn],n;
     5 
     6 int main()
     7 {
     8     while(cin>>n) {
     9         for (int i = 1; i <= n; i++)cin >> a[i];
    10         for (int i = 1; i <= n; i++)dp[i] = 1;
    11         for (int i = 2; i <= n; i++)
    12             for (int j = 1; j < i; j++) {
    13                 if (a[i] > a[j])
    14                     dp[i] = max(dp[i], dp[j] + 1);
    15             }
    16         int ans = 0;
    17         for (int i = 1; i <= n; i++)ans = max(ans, dp[i]);
    18         cout << ans << endl;
    19     }
    20     return 0;
    21 }

    HDU - 1029 Ignatius and the Princess IV

    HDU - 1069 Monkey and Banana

    POJ - 1458 Common Subsequence

     最长公共子序列

    dp[i][j] = 0                                        i==0 || j==0

              = max(dp[i][j], dp[i-1][j-1]+1)    a[i-1]==b[i-1] 

              = max(dp[i-1][j], dp[i][j-1])       a[i-1]!=b[i-1] 

     1 #include<string>
     2 #include <iostream>
     3 using namespace std;
     4 const int maxn=1e4+2;
     5 int dp[maxn][maxn];
     6 int main()
     7 {
     8     string s1,s2;
     9     while(cin>>s1>>s2)
    10     {
    11         int len1=s1.size();
    12         int len2=s2.size();
    13         for(int i=0;i<=len1;i++)
    14             for(int j=0;j<=len2;j++)
    15                 dp[i][j]=0;
    16         for(int i=0;i<=len1;i++)
    17             for(int j=0;j<=len2;j++)
    18             {
    19                 if((i==0)||(j==0))continue;
    20                 else if(s1[i-1]==s2[j-1])
    21                     dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
    22                 else
    23                 {
    24                     dp[i][j]=max(dp[i][j],dp[i][j-1]);
    25                     dp[i][j]=max(dp[i][j],dp[i-1][j]);
    26                 }
    27             }
    28         cout<<dp[len1][len2]<<endl;
    29     }
    30     return 0;
    31 }

    POJ - 2533 Longest Ordered Subsequence

     1 while(cin>>n)
     2 {
     3         for(int i=1;i<=n;i++)cin>>a[i];
     4         for(int i=1;i<=n;i++)dp[i]=1;
     5         for(int i=2;i<=n;i++)
     6         {
     7             for(int j=1;j<i;j++)
     8             {
     9                 if(a[i]>a[j])
    10                     dp[i]=max(dp[i],dp[j]+1);
    11             }
    12             ans=max(ans,dp[i]);
    13         }
    14         cout<<ans<<endl;
    15 }

    HDU - 1003 Max Sum

     1 #include<iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 const int maxn=1e5+2;
     6 long long dp[maxn],a[maxn],ans=-0xfffffffffffff;
     7 int n,t=0,T=0,l,r;
     8 
     9 int main()
    10 {
    11     cin>>n;
    12     while(n--)
    13     {
    14         cin>>t;
    15         T++;
    16         for(int i=1;i<=t;i++)cin>>a[i];
    17         for(int i=-1;i<=t;i++)dp[i]=a[i];
    18         for(int i=2;i<=t;i++)
    19             dp[i]=max(dp[i-1]+a[i],dp[i]);
    20         for(int i=1;i<=t;i++)
    21         {
    22             if(dp[i]>ans){
    23                 ans=max(ans,dp[i]);
    24                 r=i;
    25             }
    26         }
    27         long long sum=0;
    28         for(int i=r;i>=1;i--) {
    29             sum += a[i];
    30             if (sum == ans) {
    31                 l = i;
    32             }
    33         }
    34         if(T!=1)cout<<endl;
    35         cout<<"Case "<<T<<":"<<endl;
    36         cout<<ans<<" "<<l<<" "<<r<<endl;
    37     }
    38     return 0;
    39 }

    HDU - 3421 Max Sum II

    HDU - 1024 Max Sum Plus Plus

    HDU - 1244 Max Sum Plus Plus Plus

    HDU - 1087 Super Jumping! Jumping! Jumping!

    HDU - 1114 Piggy-Bank

    HDU - 1176 免费馅饼

    HDU - 1160 FatMouse's Speed

    POJ - 1661 Help Jimmy

    HDU - 1260 Tickets

    POJ - 3186 Treats for the Cows

    HDU - 1078 FatMouse and Cheese

    HDU - 2859 Phalanx

    POJ - 3616 Milking Time

    POJ - 3666 Making the Grade

    HDU - 1074 Doing Homework

    UVA - 11367 Full Tank?

    POJ - 1015 Jury Compromise 

    题意:选m人:控方和辩方会根据对候选人的喜欢程度,给候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分D和控方总分P的差的绝对值|D-P|最小。如果有多种选择方案的 |D-P| 值相同,那么选辩控双方总分之和D+P最大的方案。

    输出:要求输出这m个人的辩方总值D和控方总值P,并升序输出他们的编号

    思路:

    辩方总分和控方总分之差称为“辩控差”,辩方总分和控方总分之和称为“辩控和”。

    第i个候选人的辩方总分和控方总分之差记为V(i),之和记为S(i)。

    状态:dp[j][k]表示,取j个候选人,使其辩控差为k的所有方案中,辩控和最大的方案的辩控和。

             如果没法选j个人,使其辩控差为k,那么dp(j, k)的值就为-1。

    求:dp[m][k] (-20×m ≤ k ≤ 20×m)

    转移方程:dp[j][k]= max ( dp[j-1][k-V[i]]+S[i], dp[j][k] )

    方案dp[j][k]是由某个可行的方案 dp[j-1][x] 演化而来,可行方案 dp[j-1][x] 能演化成方案 dp[j][k] 的必要条件是:存在某个候选人i,i 在方案 dp[j-1][x] 中没有被选上,且x+V(i) = k。在所有满足该必要条件的dp[j-1][x]中,选出 dp[j-1][x]+ S(i) 的值最大的。

    程序中没有求绝对值而是将辩控差都加上修正值fix=400,以免下标为负数导致出错,此时初始条件修正为dp[0][fix] = 0,其他均为-1。DP后,从第m行的dp(m, fix)开始往两边搜索最小|D-P| 即可,第一个不为dp[m][k]!=-1的位置k就是最小|D-P|的所在。

     1 #include <iostream>
    #include <string.h> 2 #include <algorithm> 3 using namespace std; 4 int f[30][1000]; 5 //f[j][k]表示:取j个候选人,使其辩控差为k的方案中 6 //辩控和最大的那个方案(该方案称为“方案f(j,k)”)的控辩和 7 int Path[30][1000]; 8 //Path数组用来记录选了哪些人 9 //方案f(j,k)中最后选的那个候选人的编号,记在Path[j][k]中 10 int P[300];//控方打分 11 int D[300]; //辩方打分 12 13 int Answer[30];//存放最终方案的人选 14 15 int main() 16 { 17 int i,j,k; 18 int t1,t2; 19 int n,m; 20 int MinP_D;//辩控双方总分一样时的辩控差 21 int Case;//测试数据编号 22 Case=0; 23 while(scanf("%d %d",&n,&m)) 24 { 25 if(n==0&&m==0)break; 26 Case++; 27 for(i=1;i<=n;i++) 28 scanf("%d %d",&P[i],&D[i]); 29 memset(f,-1,sizeof(f)); 30 memset(Path,0,sizeof(Path)); 31 MinP_D=m*20;//题目中的辩控差为0,对应于程序中的辩控差为m*20 32 f[0][MinP_D]=0; 33 for(j=0;j<m;j++)//每次循环选出第j个人,共要选出m人 34 { 35 for(k=0;k<=MinP_D*2;k++)//可能的辩控差为[0,nMinP_D*2] 36 if(f[j][k]>=0)//方案f[j][k]可行 37 { 38 for(i=1;i<=n;i++) 39 if(f[j][k]+P[i]+D[i]>f[j+1][k+P[i]-D[i]]) 40 { 41 t1=j;t2=k; 42 while(t1>0&&Path[t1][t2]!=i)//验证i是否在前面出现过 43 { 44 t2-=P[Path[t1][t2]]-D[Path[t1][t2]]; 45 t1--; 46 } 47 if(t1==0) 48 { 49 f[j+1][k+P[i]-D[i]]=f[j][k]+P[i]+D[i]; 50 Path[j+1][k+P[i]-D[i]]=i; 51 } 52 } 53 } 54 } 55 i=MinP_D; 56 j=0; 57 while(f[m][i+j]<0&&f[m][i-j]<0) // 从中间向两边开始找辩控差最小和最大 58 j++; 59 if(f[m][i+j]>f[m][i-j]) 60 k=i+j; 61 else 62 k=i-j; 63 printf("Jury #%d ",Case); 64 printf("Best jury has value %d for prosecution and value %d for defence: ",(k-MinP_D+f[m][k])/2,(f[m][k]-k+MinP_D)/2); 65 for(i=1;i<=m;i++) 66 { 67 Answer[i]=Path[m-i+1][k]; 68 k-=P[Answer[i]]-D[Answer[i]]; 69 } 70 sort(Answer+1,Answer+1+m); 71 for(i=1;i<=m;i++) 72 printf(" %d",Answer[i]); 73 printf(" "); 74 } 75 return 0; 76 }
  • 相关阅读:
    Spring 注解@Transactional
    数据库中为什么要建立视图,它有什么好处?
    类、抽象类与接口的区别
    Comparable和Comparator的区别?
    jetty安装
    python 命令行参数sys.argv
    python--用户认证登录实现
    python--查询员工信息
    python基础
    python学习之路---编程风格规范
  • 原文地址:https://www.cnblogs.com/demian/p/10326218.html
Copyright © 2011-2022 走看看