简单dp 总结 2

来源:互联网 发布:mac os 最新的版本号 编辑:程序博客网 时间:2024/05/22 05:26

 1http://acm.hdu.edu.cn/showproblem.php?pid=1257 最小拦截系统

 

len= 0;dp[0]= INF;        for( i=1; i<=n; i++){            t= INF;            for( j=1; j<=len; j++){                if( dp[j]> a[i] && dp[j]<=t){                    temp= j;                    t= dp[j];                }            }            if( t== INF)                dp[++len]= a[i];            else dp[temp]= a[i];        }


dp存储为每个拦截系统到此为止的高度,len为系统数, a存储为炮弹高度, 每次找系统高度最低的存储~

 

2  http://acm.hdu.edu.cn/showproblem.php?pid=2844 同http://poj.org/problem?id=1742 coins

 分组背包

void zeroonepacket( int val){    for( int i=m; i>=val; i--)        dp[i]= max( dp[i], dp[i-val] + val);}void dynamic(){    int i, j, k;    for( i=0; i<n; i++){        k= 1;        while( num[i]-k+1>0){            zeroonepacket( k*w[i]);            num[i]-=k;            k*= 2;        }        zeroonepacket( num[i]*w[i]);    }}

 

对于此题,下面效率更高

void dynamic(){      int i, j, k;      for( i=0; i<n; i++){          memset( use, 0, sizeof( use));          for( j= w[i]; j<=m; j++){              if( !dp[j]&& dp[j-w[i]] && use[ j-w[i]]< num[i]){                  use[j]= use[j-w[i]] + 1;                  dp[j]= true;                  ans++;              }          }      }  } 


use存储每样价值币种使用的数量, num存储每样币种共多少, dp表示此数量是否可达

 

 

3  http://acm.hdu.edu.cn/showproblem.php?pid=1159Common Subsequence

对于给的a、 b序列,选择 下标递增的最大公共子序列

m=strlen(a);n=strlen(b);        start[0][0]=0;        for( i=1; i <= m; ++i)    start[i][0]=0;        for( i=1; i <= n; ++i)    start[0][i]=0;        for( i=1; i <= m; ++i )            for( j=1; j <=n; ++j)            {                if(a[i-1]==b[j-1]) start[i][j]=start[i-1][j-1]+1;                else if(start[i-1][j]>start[i][j-1])    start[i][j]=start[i-1][j];                else start[i][j] = start[i][j-1];            }        printf("%d\n",start[m][n]);



 4 http://acm.hdu.edu.cn/showproblem.php?pid=1503  Advanced Fruits

同样是求最大公共子序列, 要求输出最小序列包含给定两个串的所有字母

 

在上题基础上,加一个road记录路径,dp存储为公共子序列长度, out即为所求序列,,

road[i][j]==1 (a[i-1]== b[j-1] )

road[i][j]==0 (dp[i][j-1]> dp[i-1][j] && a[i-1]!= b[j-1] )

 road[i][j]==-1 (dp[i][j-1]<dp[i-1][j] && a[i-1]!= b[j-1] )

road按照以上增加进去

输出倒叙遍历,同时对于遍历后i>1或j>1情况,输出a或b串剩下的字符


 

原创粉丝点击