洛谷1282 多米诺骨牌

  是传送门啊

是一道时隔多年不太会写的题qwq

思路:

  想了一会 觉得可以设f[i][j]为前i个牌旋转j次的最小上下点数差

  但是这样好像又不对 因为这个局部最优并不一定可以得到全局最优啊

  于是又想了想 终于唤起了原来写这道题的记忆

  令f[i][j]为前i张牌 上面的骨牌点数和为j的最小旋转次数

CODE:

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int a[1010],b[1010];//a:上 ;b:下 
 5 int f[1010][6010];
 6 int main()
 7 {
 8     int n,s=0,s1=0,s2=0,sum1;
 9     cin>>n;
10     for(int i=1;i<=n;i++)
11     {
12         cin>>a[i]>>b[i];
13         s+=a[i]+b[i];
14         s1+=a[i];
15         s2+=b[i];
16     }
17     sum1=abs(s1-s2);
18     for(int i=1;i<=n;i++)
19     {
20         for(int j=0;j<=6*n;j++)
21         f[i][j]=210000000;
22     }
23     f[1][a[1]]=0;f[1][b[1]]=1;
24     for(int i=2;i<=n;i++)
25     {
26         for(int j=1;j<=i*6;j++)
27         {
28             if(j>a[i]) f[i][j]=min(f[i][j],f[i-1][j-a[i]]);
29             if(j>b[i]) f[i][j]=min(f[i][j],f[i-1][j-b[i]]+1);
30         } 
31     }
32     int mins=210000000,mint=210000000;
33     for(int i=0;i<=6*n;i++)
34     {
35         if(f[n][i]!=210000000)
36         {
37             int sum=abs(s-i-i);
38             if(sum<mins)
39             {
40                 mins=sum;
41                 mint=f[n][i];
42             }
43             if(sum==mins&&f[n][i]<mint) mint=f[n][i];
44         }
45     }
46     if(mins>=sum1) cout<<0;
47     else cout<<mint;
48     return 0;
49 } 
贴上以前的code啊

猜你喜欢

转载自www.cnblogs.com/forward777/p/10339753.html