单调队列 -- F. Fake Maxpooling

F. Fake Maxpooling

题意:
给你一个n * m的矩阵, 矩阵值为 行号 i 、 列号 j的lcm(最小公倍数), 求这个n * m 矩阵所有 k * k 子矩阵中最大值的和。

思路:
单调队列求每行窗口k内的最大值,并记录到broad矩阵中, 在对broad矩阵每列用单调矩阵求一遍窗口k内的最大值, 把每个子矩阵的贡献加到起来就行了。
单调矩阵是什么,详解在这里
我这里是用数组qu和数组的前后指针head、tail模拟的单调队列,用双端队列deque会使代码要清爽一些。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e3 + 5;
int mp[maxn][maxn], broad[maxn][maxn]int qu[maxn], head, tail; //qu为但单调队列,head为前指针,tail为后指针

int gcd(int n, int m){
	int t;
	while(m != 0){
		t = n % m;
		n = m; 
		m = t;
	}
	return n;
}

int main(){
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= n; i++)     //得到lcm矩阵
	   for(int j = 1; j <= m; j++)
	      mp[i][j] = i / gcd(i, j) * j;  
	
	long long sum = 0;
	if(k > 1){
			
	  for(int i = 1; i <= n; i++){
		  head = 1;
		  tail = 0;

		  for(int j = 1; j <= m; j++){      //求每个子矩阵的最大值,用单调递减队列                          
		                                    //若求最小值用单调递增队列 
		  	 if(tail < head) qu[++tail] = j;
		  	 else {
		  	 	if(j >= k && qu[head] < j - k + 1) head++;
			    while(tail >= head && mp[i][j] >= mp[i][qu[tail]]) tail--;
			    qu[++tail] = j;
			 }
			 			 
			 if(j >= k) broad[i][j] = mp[i][qu[head]];		 
		  }
	  }
	  	 
	  for(int i = k; i <= m; i++){
	  	  head = 1;
	  	  tail = 0;
	  	  for(int j = 1; j <= n; j++){
	  		 if(tail < head) qu[++tail] = j;
	  		 else {
	  		 	 if(j >= k && qu[head] < j - k + 1) head++;
	  		 	 while(tail >= head && broad[j][i] >= broad[qu[tail]][i]) tail--;
	  		 	 qu[++tail] = j;
			 }
			 
			 if(j >= k) sum += broad[qu[head]][i];
		  }
	  }
	  
	  
	}
	else {
		for(int i = 1; i <= n; i++)
		   for(int j = 1; j <= m; j++)
		      sum += mp[i][j];
	}
	printf("%lld\n", sum);
	
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
请解释此段代码class GATrainer(): def __init__(self, input_A, input_B): self.program = fluid.default_main_program().clone() with fluid.program_guard(self.program): self.fake_B = build_generator_resnet_9blocks(input_A, name="g_A")#真A-假B self.fake_A = build_generator_resnet_9blocks(input_B, name="g_B")#真B-假A self.cyc_A = build_generator_resnet_9blocks(self.fake_B, "g_B")#假B-复原A self.cyc_B = build_generator_resnet_9blocks(self.fake_A, "g_A")#假A-复原B self.infer_program = self.program.clone() diff_A = fluid.layers.abs( fluid.layers.elementwise_sub( x=input_A, y=self.cyc_A)) diff_B = fluid.layers.abs( fluid.layers.elementwise_sub( x=input_B, y=self.cyc_B)) self.cyc_loss = ( fluid.layers.reduce_mean(diff_A) + fluid.layers.reduce_mean(diff_B)) * cycle_loss_factor #cycle loss self.fake_rec_B = build_gen_discriminator(self.fake_B, "d_B")#区分假B为真还是假 self.disc_loss_B = fluid.layers.reduce_mean( fluid.layers.square(self.fake_rec_B - 1))###优化生成器A2B,所以判别器结果越接近1越好 self.g_loss_A = fluid.layers.elementwise_add(self.cyc_loss, self.disc_loss_B) vars = [] for var in self.program.list_vars(): if fluid.io.is_parameter(var) and var.name.startswith("g_A"): vars.append(var.name) self.param = vars lr = 0.0002 optimizer = fluid.optimizer.Adam( learning_rate=fluid.layers.piecewise_decay( boundaries=[ 100 * step_per_epoch, 120 * step_per_epoch, 140 * step_per_epoch, 160 * step_per_epoch, 180 * step_per_epoch ], values=[ lr, lr * 0.8, lr * 0.6, lr * 0.4, lr * 0.2, lr * 0.1 ]), beta1=0.5, name="g_A") optimizer.minimize(self.g_loss_A, parameter_list=vars)
最新发布
06-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值