2017.3.12 分割矩阵 失败总结

来源:互联网 发布:淘宝原创衣服怎么弄 编辑:程序博客网 时间:2024/05/29 01:52

        感觉再也做不出题了 QAQ、、

        其实,第一眼看上去我依然是懵逼的,

        发现只要有左上角的坐标和左下角的坐标是可以10^4 预处理区间和的    简单划了一下只有O((a*b)^n)的做法、

          然后发现沿数字边缘划实际上只是告诉你只能拆成矩形, 而且只与要求分成的块数有关,所以“田”字也是需要划3刀的、

              均方差最小应该就是每个矩阵的和相差最小吧、

                 所以要求满足这个条件下的n个不重复矩形?

                   蒟蒻想过类似划分 数的dp,但这个均方差实在魔性,实在不知怎么取值,贪心二分对于小数+误差似乎也无能为力。


        

           、、、   (ノಠ益ಠ)ノ彡┻━┻

                又是倒在了正解门口、、

                                    其实是挂在标准差上了(一开始我连均方差是啥都不知道

                     均方差不是线性函数吧,怎么可以递推?

                      如果平均数改变,三个数的方差怎么可以由前两个数的方差推来?

                       如果把k也记进去岂不是很慢?


                               看标程1分钟、、呵呵,

     我TM智障吗!!!

                     

                     矩形都定下来了平均数不就出来了吗?

                    对每个矩阵选个差最小的不就好了?

                        有时dp要放长远,考虑全局、

                         

                     再次暴露了数学弱的事实

                             


                   不过还有个问题,如果是二维dp的话,只记录左上,右下,那:

怎么办?


           好吧,没想到他是正面gang这个题的,直接切、、

          枚举横切纵切(竟然不会超时),直接记搜下放,就不用考虑内部工作了,而且记搜也能消除部分冗杂、 

            就是优化到一种层次的暴力                  

         考虑了所有矩形, 所以对于上述的情况,因为在一个横行的内部和纵列的内部,所以它其实已经把所有可能的情况都搜出来了


          感觉正面递推难度颇大,但应该会更快。

          有空计算一下时间复杂度。、


码:

#include<iostream>#include<cstdio>using namespace std;#include<cmath>double f[11][11][11][11][11];double he[11][11],zuo[11][11],s[11][11];int i,j,n,k,a,b;double jun;double dfs(int x1,int y1,int x2,int y2,int k){if(f[x1][y1][x2][y2][k])return f[x1][y1][x2][y2][k];if(k==1)//临界情况   {      f[x1][y1][x2][y2][k]=((he[x2][y2]-he[x1-1][y2]-he[x2][y1-1]+he[x1-1][y1-1])-jun);      f[x1][y1][x2][y2][k]*=f[x1][y1][x2][y2][k];      // printf("%.2f\n",f[x1][x2][y1][y2][k]);           return f[x1][y1][x2][y2][k];          }       int i,j;double lin=1e9;       for(i=x1;i<x2;i++)//枚举横切   for(j=1;j<k;j++)   {   if((x2-i)*(y2-y1+1)<j||(i-x1+1)*(y2-y1+1)<j)break;   lin=min(dfs(x1,y1,i,y2,j)+dfs(i+1,y1,x2,y2,k-j),lin);   }        for(i=y1;i<y2;i++)       for(j=1;j<k;j++)   {     if((y2-i)*(x2-x1+1)<j||(i-y1+1)*(x2-x1+1)<j)break;   lin=min(dfs(x1,y1,x2,i,j)+dfs(x1,i+1,x2,y2,k-j),lin);   }    f[x1][y1][x2][y2][k]=lin;  // cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" "<<lin<<endl;       return lin;}int main(){scanf("%d%d%d",&a,&b,&k);  for(i=1;i<=a;i++)  for(j=1;j<=b;j++)  {         scanf("%lf",&s[i][j]); jun+=s[i][j];   }jun=1.000000*jun/(1.000000*k);for(i=1;i<=a;i++)for(j=1;j<=b;j++){he[i][j]=he[i-1][j]+zuo[i][j-1]+s[i][j];zuo[i][j]=zuo[i][j-1]+s[i][j];//cout<<i<<" "<<j<<" "<<he[i][j]<<endl;   //  printf("%d   %d   %.2f\n",i,j,he[i][j]);}//cout<<jun;//cout<<dfs(1,1,a,b,k)<<" ";printf("%.2lf",sqrt(1.000000*dfs(1,1,a,b,k)/(1.000000*k)));}

1、用double注意变量赋值和读入类型!!

2、if里写全了!


 

            

0 0
原创粉丝点击