题意:太难懂了,最开始给你一个数列 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 }
View Code

 

posted on 2015-04-14 23:40  dark_dream  阅读(138)  评论(0编辑  收藏  举报