poj3666
题意:将一串数改成非严格的上升或者非严格的下降,最少要改变多少
分析:一道非常经典的dp题,看了网上别人的思路才解决的。我们的目的是要将其改成非严格的单增或单减,并且求其最少的改变,所以对于那些不符合要求的点,我们使它变得跟前一个或者是后一个相同时,我们得到的改变才是最少的,这样,我们每次做改变之后的元素,必定会变味原来序列中的元素。所以我们得到如下的dp方程,令dp[i][j]为第i个位置改为B[j]或C[j]时,前i-1个有序的最小代价
dp[i+1][j]=min(dp[i][k])+abs(a[i]-b[j])(0<=k<=j),因为要保证为递增活着递减,所以k不能大于j
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <vector> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <bitset> 10 #include <cmath> 11 #include <queue> 12 #include <stack> 13 using namespace std; 14 const int maxn=2020; 15 int a[maxn],b[maxn],c[maxn]; 16 int dp1[maxn][maxn],dp2[maxn][maxn]; 17 int n; 18 bool cmp(int x,int y) 19 { 20 return x>y; 21 } 22 int main() 23 { 24 while(cin>>n) 25 { 26 for(int i=0;i<n;i++) 27 cin>>a[i]; 28 for(int i=0;i<n;i++){ 29 b[i]=a[i]; c[i]=a[i]; 30 } 31 sort(b,b+n); //求上升的情况 32 sort(c,c+n,cmp); //求下降的情况 33 memset(dp1,0,sizeof(dp1)); 34 memset(dp2,0,sizeof(dp2)); 35 for(int i=0;i<n;i++){ 36 int minx=dp1[i][0]; 37 for(int j=0;j<n;j++){ 38 minx=min(minx,dp1[i][j]); 39 dp1[i+1][j]=minx+abs(a[i]-b[j]); 40 } 41 } 42 int min_up=1000000000; 43 for(int i=0;i<n;i++) 44 min_up=min(min_up,dp1[n][i]); 45 for(int i=0;i<n;i++){ 46 int miny=dp2[i][0]; 47 for(int j=0;j<n;j++){ 48 miny=min(miny,dp2[i][j]); 49 dp2[i+1][j]=miny+abs(a[i]-c[j]); 50 } 51 } 52 int min_down=1000000000; 53 for(int i=0;i<n;i++) 54 min_down=min(min_down,dp2[n][i]); 55 cout<<min(min_up,min_down)<<endl; 56 } 57 return 0; 58 }
poj2392
题意:一群奶牛修房子,每个奶牛有材料的高度,数量,以及所能允许其上的最大高度,求房子最高能修多大
分析:这题还是一个多重背包模型,我们还需将房子按照其允许的高度从打到小进行排序,因为只有这样,才能在每次往上加的时候满足条件,其他的同《挑战程序设计》62到64页的多重部分和问题,最后进行统计找出最大的数即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <vector> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <bitset> 10 #include <cmath> 11 #include <queue> 12 #include <stack> 13 using namespace std; 14 const int maxn=40040; 15 int dp[maxn]; 16 typedef struct p 17 { 18 int h,a,c; 19 }p; 20 p s[401]; 21 int n; 22 bool cmp(p x,p y) 23 { 24 return x.a<y.a; 25 } 26 int main() 27 { 28 while(cin>>n) 29 { 30 for(int i=0;i<n;i++) 31 cin>>s[i].h>>s[i].a>>s[i].c; 32 memset(dp,-1,sizeof(dp)); 33 sort(s,s+n,cmp); 34 dp[0]=0; 35 for(int i=0;i<n;i++){ 36 for(int j=0;j<=s[i].a;j++){ 37 if(dp[j]>=0){ 38 dp[j]=s[i].c; 39 }else if(j<s[i].h||dp[j-s[i].h]<=0) 40 dp[j]=-1; 41 else 42 dp[j]=dp[j-s[i].h]-1; 43 } 44 } 45 int k; 46 for(int i=s[n-1].a;i>=0;i--){ 47 if(dp[i]>=0){ 48 k=i; break; 49 } 50 } 51 cout<<k<<endl; 52 } 53 return 0; 54 }