R_Z
我永远喜欢珂朵莉

P1282 多米诺骨牌

本题是dp。

f [ i ] [ j ] 是表示:差为 j 时, 到第 i 个骨牌需要的步数,初始化为无穷大;

实质是一个背包问题,因为有负数下标,因此多加一个mod (偷懒)  把数组整体右移。

  • Q1:dp会不会反了?
  • 其实就是个逆向思维,用脑想一下 (其实也不用脑的) j是由 j-dis(个体差值) 得来的,j-dis实际上就是加上 dis 所以根本没有翻转;
  • Q2:ans>=1000 break?
  • 看题目!看题目!看题目!最小差值,关键就是 j+mod 的含义,就是从小差值开始,所以只要有一个不是无穷大,就是答案了。
  • 对了,其实不用一万的,只是我在作死。

巧妙的题目,无脑的我……

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 #define mid ((l+r)>>1)
 8 #define maxn 150
 9 #define mod 10000
10 #define reg register 
11 #define ll long long
12 #define ull unsigned long long
13 #define inf 0x3f3f3f3f 
14 #define rep(a,b,c) for(reg int a=b;a<=c;a++) 
15 #define Rep(a,b,c) for(reg int a=b;a<c;a++)
16 #define down(a,b,c) for (reg int a=b;a>=c;a--)
17 #define Down(a,b,c) for (reg int a=b;a>c;a--)
18 
19 //struct yl{
20 //    int beg,sto,til;
21 //}s[maxn];
22 int f[1010][20010];
23 int up[1005],down[1005];
24 
25 inline int read()
26 {
27     char ch=getchar();
28     int k=0,sign=1;
29     while (ch<'0' || ch>'9') {
30         if (ch=='-') sign=-1;
31         ch=getchar();
32     }
33     while (ch>='0'&&ch<='9') k=k*10+(ch^48),ch=getchar();
34     return k*sign;
35 }
36 //bool cmp(yl a,yl b) {return a.beg>b.beg;}
37 //int gcd(int x,int y){return x%y==0?y:gcd(y,x%y);}
38 
39 //void P()
40 //{
41 //    rep(i,1,n) 
42 //    {
43 //        rep(j,1,n)
44 //        {
45 //            printf("%10d ",f1[i][j]);
46 //        }
47 //        putchar(10);
48 //    }
49 //}
50 int main()
51 {
52 //    freopen("qnm.in","r",stdin);
53 //    freopen("cnm.out","w",stdout);
54     int n=read();
55     rep(i,1,n)
56     {
57         up[i]=read();
58         down[i]=read();
59     }
60     memset(f,0x6f,sizeof(f));
61     f[0][mod]=0;
62     rep(i,1,n)    rep(j,-10000,10000)
63     {
64         int dis=up[i]-down[i];
65         f[i][j+10000]=min(f[i-1][j+mod-dis],f[i-1][j+mod+dis]+1);
66     }
67     int ans=f[n][mod];
68     rep(i,1,mod) 
69     {
70         ans=min(ans,f[n][i+mod]); 
71         if (ans<=1000)
72         {
73             printf("%d\n",ans);
74             break;
75         }
76     }
77     return 0;
78 }
View Code
  • 代码C++,1.46KB
  • 提交时间2018-02-08 23:53:41
  • 耗时/内存864ms, 79277KB

2018-02-09 00:44:33

 

posted on 2018-02-09 00:47  R_Z  阅读(122)  评论(0编辑  收藏  举报