1. 程式人生 > >LRJ入門經典-0905郵票和信封305

LRJ入門經典-0905郵票和信封305

原題

LRJ入門經典-0905郵票和信封305
難度級別:B; 執行時間限制:1000ms; 執行空間限制:256000KB; 程式碼長度限制:2000000B
試題描述

假定一張信封最多貼5張郵票,如果只能貼1分和3分的郵票,可以組成面值1-13以及15,但不能組成面值14。我們說:對於郵票組合{1,3}以及數量上限S=5,最大連續郵資為13。

輸入S和若干郵票組合,選出最大連續郵資最大的一個組合。如果有多種並列,保證選出的組合中郵票張數最多。如果還有並列,保證最大的郵票面值儘可能小

輸入
輸入第一行包含一個正整數S(S<=10),表示郵票數量上限
第二行為一個正整數N(N<=10)
以下N行,每行代表一個郵票集合,第一個數表示集合中郵票的數量,後面從小到大依次表示每張郵票的面值(郵票面值不超過100)
輸出
輸出包括兩行,第一行為最大連續郵資,第二行依次輸出該連續郵資對應的郵票組合(多解時按照題目描述的要求輸出最恰當的組合)
輸入示例
5
2
4 1 4 12 21
4 1 5 12 28
輸出示例
71
1 4 12 21

分析

 

程式碼

 1 #include<iostream>
 2 #include<algorithm>
 3
#include<cstring> 4 using namespace std; 5 struct P 6 { 7 int s,x[110]; 8 }a[11]; 9 int dp[11][11000]; 10 inline int minn(int xx,int yy) 11 { 12 for(int i=1;i<yy;i++) 13 for(int j=i;j<yy;j++) 14 if(i+j==yy && (dp[xx][i]+dp[xx][j])<dp[xx][yy]) dp[xx][yy]=dp[xx][i]+dp[xx][j]; 15 } 16 int main() 17 { 18 int n,m,sum=0; 19 cin>>n>>m; 20 for(int i=1;i<=m;i++) 21 { 22 cin>>a[i].s; 23 for(int j=1;j<=a[i].s;j++) 24 { 25 cin>>a[i].x[j]; 26 sum+=a[i].x[j]*n; 27 } 28 } 29 memset(dp,9999,sizeof(dp)); 30 for(int i=1;i<=m;i++) 31 { 32 if(a[i].x[1]!=1) 33 { 34 dp[i][0]=0; 35 continue; 36 } 37 for(int j=1;j<=a[i].s;j++) dp[i][a[i].x[j]]=1; 38 for(int j=1;j<=1000;j++) 39 { 40 if(dp[i][j]==1) 41 { 42 if(dp[i][j]>n) 43 { 44 dp[i][0]=j-1; 45 break; 46 } 47 continue; 48 } 49 dp[i][j]=min(dp[i][j],minn(i,j)); 50 if(dp[i][j]>n) 51 { 52 dp[i][0]=j-1; 53 break; 54 } 55 } 56 } 57 int ii=-1,min_dp=-1,min_s=0,min_o=99999999; 58 for(int i=1;i<=m;i++) 59 { 60 if(dp[i][0]>min_dp) min_dp=dp[i][0],min_s=a[i].s,min_o=a[i].x[a[i].s],ii=i; 61 if(dp[i][0]==min_dp) 62 { 63 if(a[i].s>min_s) min_dp=dp[i][0],min_s=a[i].s,min_o=a[i].x[a[i].s],ii=i; 64 if(a[i].s==min_s) 65 if(a[i].x[a[i].s]<min_s) min_dp=dp[i][0],min_s=a[i].s,min_o=a[i].x[a[i].s],ii=i; 66 } 67 } 68 /*cout<<endl<<endl; 69 for(int i=1;i<=1000;i++) cout<<dp[1][i]<<" "; 70 cout<<endl<<endl; 71 for(int i=1;i<=1000;i++) cout<<dp[2][i]<<" "; 72 cout<<endl<<endl;*/ 73 cout<<min_dp<<endl; 74 cout<<a[ii].x[1]; 75 for(int i=2;i<=a[ii].s;i++) cout<<" "<<a[ii].x[i]; 76 return 0; 77 } 78 /* 79 10 80 2 81 5 1 7 16 31 88 82 5 1 15 52 67 99 83 */