题意:太难懂了,最开始给你一个数列 wi ,还有一个转移矩阵 M[m][s], 你最开始只能从 M第一列选一个数 L1,如果选的第K个数,接下来只能从第 k&(m-1)取数,
问你|li-wi| 和的最小值及路径。
解题思路:DP加记录路径。
解题代码:
1 // File Name: e.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月14日 星期二 20时35分51秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 int dp[1005][136]; 28 struct node{ 29 int r,c; 30 node(){} 31 node(int _r, int _c) 32 { 33 r = _r; 34 c = _c; 35 } 36 }from[1004][136]; 37 int a[1005]; 38 int m ,s; 39 int mp[150][150]; 40 int ABS(int x) 41 { 42 if(x < 0 ) 43 return -x; 44 return x; 45 } 46 int n; 47 void print(int r, int c ,int d) 48 { 49 //printf("%d %d\n",r,c); 50 if(d == n) 51 { 52 printf("%d ",c); 53 return ; 54 } 55 print(from[n+1-d][r].r,from[n+1-d][r].c, d + 1); 56 printf("%d ",c); 57 } 58 int main(){ 59 freopen("quant.in","r",stdin); 60 freopen("quant.out","w",stdout); 61 scanf("%d",&n); 62 for(int i = 1;i <= n;i ++) 63 scanf("%d",&a[i]); 64 scanf("%d %d",&m,&s); 65 for(int i = 0 ;i < m;i ++) 66 for(int j = 0 ;j < s; j ++) 67 scanf("%d",&mp[i][j]); 68 memset(dp,-1,sizeof(dp)); 69 dp[1][0] = 0; 70 for(int i= 1;i <= n;i ++) 71 { 72 for(int j = 0 ;j < m;j ++) 73 { 74 if(dp[i][j] == -1) 75 continue; 76 for(int t = 0 ;t < s ; t ++) 77 { 78 if(dp[i+1][t&(m-1)] == -1 || dp[i][j] + ABS(mp[j][t] - a[i]) < dp[i+1][t&(m-1)]) 79 { 80 dp[i+1][t&(m-1)] = dp[i][j] + ABS(mp[j][t] - a[i]); 81 from[i+1][t&(m-1)] = node(j,t); 82 } 83 } 84 } 85 } 86 int mi = 1e9 + 10000; 87 int si = 0 ; 88 for(int i = 0 ;i < m ;i ++ ) 89 { 90 if(dp[n+1][i] != -1 && dp[n+1][i] < mi) 91 { 92 mi = dp[n+1][i]; 93 si = i ; 94 } 95 } 96 printf("%d\n",mi); 97 print(from[n+1][si].r,from[n+1][si].c,1); 98 return 0; 99 }
没有梦想,何谈远方