A

 按位讨论,取最小值;

B

 数据范围不大,首先要确定枚举角度;

 状压枚举palindromes的列比较科学;

 列确定后,目标就是求获得rcnt行的最小代价:

  dp[i][cnt]表示扫描到第i行,已经有cnt个满足要求的最小代价;

 根据对称性,只要扫描n/2行,而从第i行获得j个增益的代价cost[i][j],可以另外处理:

  当考虑cost[i][j]时,根据对称性,实际是考虑2行(i,n-i),从这2行获得增益的情况只有3种:0,1,2,

  然后,讨论每种情况下的代价:

    0, 只需保证列满足要求;

    1, 任一行满足要求,取最小值;

    2, 2行 同时满足要求;

  然后各种特判...

 #include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
#define maxn (1<<14)
#define INF 4000
#define rep(i,n) for(int i=0 ; i<(n) ; i++ )
class PalindromeMatrix {
public:
int minChange(vector <string>, int, int);
};
vector<int> valid;
int bit[maxn],n,m;
int check(int mask,int len) {
rep (i,len/) {
int p = mask&(<<i);
int q = mask&(<<(len-i-));
if (p!=q) return ;
}
return ;
}
void init() {
rep (i,maxn) {
if ((i<<)<maxn)bit[i<<] = bit[i];
if ((i<<|)<maxn)bit[i<<|] = bit[i]+;
}
rep (i,(<<m)) if (check(i,m)) valid.push_back(i);
}
int dp[][],cost[][];
void init(vector<string> A,int mask) {
rep (i,) rep (j,) dp[i][j]=INF;
rep (i,) rep (j,) cost[i][j]=INF;
rep (i,n/) {
string s1 = A[i];
string s2 = A[n--i];
// cout<<"s1:"<<s1<<endl;
// cout<<"s2:"<<s2<<endl;
int res = ;
// r=0
rep (j,m) if (mask&(<<j)) {
if (s1[j]!=s2[j]) res++;
}
cost[i][]=res;
// r=2
res = ;
//printf("cal:cost[%d][2]\n",i);
rep (j,m/) {
int a=j,b=m--j;
if ( (mask&(<<a)) || (mask&(<<b)) ) {
// printf("s1[%d]:%c s1[%d]:%c s2[%d]:%c s2[%d]:%c\n",a,s1[a],b,s1[b],a,s2[a],b,s2[b]);
int tmp = (s1[a]+s2[a]+s1[b]+s2[b]-*(int)'');
tmp = min(tmp,-tmp);
res += tmp;
}else {
if (s1[a]!=s1[b]) res++;
if (s2[a]!=s2[b]) res++;
}
}
cost[i][]=res;
// r=1,s1
res=;
rep (j,m/) {
int a=j,b=m--j;
if (s1[a] != s1[b]) {
if ( (mask&(<<a)) && (mask&(<<b)) ) {
int tmp = s1[a]+s1[b]+s2[a]+s2[b]-*'';
res += min(tmp,-tmp);
} else res ++;
} else {
if ( (mask&(<<a)) && (mask&(<<b)) ) {
int tmp = s1[a]+s1[b]+s2[a]+s2[b]-*'';
res += min(tmp,-tmp);
} else if ( (mask&(<<a)) ) {
res += (s1[a]!=s2[a]);
} else if ( (mask&(<<b)) ) {
res += (s1[b]!=s2[b]);
}
}
}
cost[i][]=res;
// r=1,s2
res=;
rep (j,m/) {
int a=j,b=m--j;
if (s2[a] != s2[b]) {
if ( (mask&(<<a)) && (mask&(<<b)) ) {
int tmp = s1[a]+s1[b]+s2[a]+s2[b]-*'';
res += min(tmp,-tmp);
} else res ++;
} else {
if ( (mask&(<<a)) && (mask&(<<b)) ) {
int tmp = s1[a]+s1[b]+s2[a]+s2[b]-*'';
res += min(tmp,-tmp);
} else if ( (mask&(<<a)) ) {
res += (s1[a]!=s2[a]);
} else if ( (mask&(<<b)) ) {
res += (s1[b]!=s2[b]);
}
}
}
cost[i][]=min(cost[i][],res);
}
}
void PrintMask(int mask) {//printf("var:%d mask:",mask);
while (mask) {
// printf("%d",mask&1?1:0);
mask>>=;
}//printf("\n");
}
int solv(vector<string> A,int nr,int nc) {
int ans = INF;
rep (s,(<<m)) if (bit[s]==nc) {
PrintMask(s);
init(A,s);
dp[][] = ;
rep (i,n/) rep (j,nr+)
if (dp[i][j]!=INF) {
rep (k,) {
int nxtj = min(nr,k+j);
dp[i+][nxtj] = min(dp[i+][nxtj],dp[i][j]+cost[i][k]);
}
}
ans = min(ans,dp[n/][nr]);
}
return ans;
}
int PalindromeMatrix::minChange(vector <string> A, int nr, int nc) {
init();
n = A.size();
m = A[].size();
int ans= solv(A,nr,nc);
return ans;
}

C

 刚开始想按b递增考虑,每加入一条线时的增加数应该很好算,后来发现情况非常复杂,很难发现结论.

 题解的结论是从交点个数得到的.

 尝试证明一下:

  加入一条直线时,每产生一个交点,就划分出一个新的区域,最后想象无穷远处有条封闭的边界,与延时到无限远的直线构成新的区域,

  所以结论为  1 + 不同的交点个数.

 

 #include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime> using namespace std; class LotsOfLines {
public:
long long countDivisions(int, int);
};
int gcd(int a,int b) {
if (b==) return a;
return gcd(b,a%b);
}
long long sum[][];
long long LotsOfLines::countDivisions(int A, int B) {
long long ans = ;
A-- , B--;
for (int q= ; q<=A ; q++ ) {
for (int p= ; p<=B ; p++ ) {
int x = gcd(p,q)==?:;
sum[q][p] = sum[q-][p] + sum[q][p-] - sum[q-][p-] + x;
}
}
for (int a= ; a<=A ; a++ ) {
for (int b= ; b<=B ; b++ ) {
ans ++;
if (a)
ans += + sum[a][b] + sum[a][B-b];
}
}
return ans;
} //Powered by [KawigiEdit] 2.0!

SRM 600 DIV1的更多相关文章

  1. topcoder srm 600 div1

    problem1 link 首先,如果一个数字的某一位是1但是$goal$的这一位不是1,那么这个数字是不用管它的.那么对于剩下的数字,只需要统计在$goal$为1的位上,这些数字对应位上也是1的数字 ...

  2. Topcoder SRM 600 div1题解

    日常TC计划正式启动! Easy(250pts): 题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数.问至少删去多少个数,使得你永远无法 ...

  3. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  4. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  5. SRM 146 DIV1 600

    Problem Statement      Masterbrain is a two player board game in which one player decides on a secre ...

  6. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  7. TopCoder SRM 722 Div1 Problem 600 DominoTiling(简单插头DP)

    题意  给定一个$12*12$的矩阵,每个元素是'.'或'X'.现在要求$1*2$的骨牌铺满整个矩阵, 'X'处不能放置骨牌.求方案数. 这道题其实和 Uva11270 是差不多的,就是加了一些条件. ...

  8. 图论 SRM 674 Div1 VampireTree 250

    Problem Statement      You are a genealogist specializing in family trees of vampires. Vampire famil ...

  9. SRM 600(1-250pt,500pt)

    DIV1 250pt 题意:给定一个vector<int>A,若能从里面选出一些数,使得他们按位或的值为x,则称x为吉利数.给定k,问最少要从A里面去掉多少个数,才能使k变为不吉利数. 解 ...

随机推荐

  1. SlidingMenu导入编译用法--Eclipse和IDEA

    非常多側滑的应用都用的是开源库SlidingMenu, 效果不错,下面是我用上的效果图,因为近期换成了IDEA(IntelliJ)编辑器,昨天上网找了全部的教程都是关于在Eclipse导入的方法,摸索 ...

  2. C#切割指定区域图片操作

    使用winform制作了一个切割图片的功能,切一些固定大小的图片,比如头像.界面如图: 打开本地图片 OpenFileDialog opdialog = new OpenFileDialog(); o ...

  3. 自定义控件【圆形】圆角 BitmapShader

    关于缩放比例         本例中,我们会为BitmapShader设置了一个matrix,目的是按比例放大或者缩小bitmap,并移动到View控件的中心,我们不会让view的宽高大于我们bitm ...

  4. CSS3 过滤

    CSS3 过滤 通过CSS3,我们可以在不适用flash动画或JavaScript的情况下,当元素从一种样式变换为另一种样式时为元素添加效果. 浏览器支持 属性 浏览器支持 transition   ...

  5. python zip文件密码爆破

    #!/usr/bin/env # coding=UTF-8 import zipfile import threading import os import sys class CrackZip: d ...

  6. 武汉科技大学ACM :1004: 华科版C语言程序设计教程(第二版)课后习题3.7

    Problem Description 输入无符号短整数k[hex.]和p[oct.],将k的高字节作为结果的低字节,p的高字节作为结果的高字节组成一个新的整数. Input k[hex.]和p[oc ...

  7. 多线程09-Lock和Condition

    1.概念 Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 2. ...

  8. 1.3.4 try-with-resources (TWR)

    其基本设想是把资源(比如文件或类似的东西)的作用域限定在代码块内,当程序离开这个代码块时,资源会被自动关闭: 要确保try-with-resources生效,正确的用法是为各个资源声明独立变量: 目前 ...

  9. JavaScript获取Select下拉框Option的Value和Text值的方法

    Js获取select下拉列表框各个Option的Value值相对比较容易,不过获取Text值却有点麻烦,对于一个初学JavaScript的 新手来说,可能一时还无从下手,那么就请看下本文的方法,以一个 ...

  10. PHP安全设置(转载)

    大家都知道PHP已经是当前最流行的Web应用编程语言了.但是也与其他脚本语言一样,PHP也有几个很危险的安全漏洞.所以在这篇教学文章中,我们将大致看看几个实用的技巧来让你避免一些常见的PHP安全问题. ...