SRM 600 DIV1
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的更多相关文章
- topcoder srm 600 div1
problem1 link 首先,如果一个数字的某一位是1但是$goal$的这一位不是1,那么这个数字是不用管它的.那么对于剩下的数字,只需要统计在$goal$为1的位上,这些数字对应位上也是1的数字 ...
- Topcoder SRM 600 div1题解
日常TC计划正式启动! Easy(250pts): 题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数.问至少删去多少个数,使得你永远无法 ...
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- SRM 146 DIV1 600
Problem Statement Masterbrain is a two player board game in which one player decides on a secre ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 722 Div1 Problem 600 DominoTiling(简单插头DP)
题意 给定一个$12*12$的矩阵,每个元素是'.'或'X'.现在要求$1*2$的骨牌铺满整个矩阵, 'X'处不能放置骨牌.求方案数. 这道题其实和 Uva11270 是差不多的,就是加了一些条件. ...
- 图论 SRM 674 Div1 VampireTree 250
Problem Statement You are a genealogist specializing in family trees of vampires. Vampire famil ...
- SRM 600(1-250pt,500pt)
DIV1 250pt 题意:给定一个vector<int>A,若能从里面选出一些数,使得他们按位或的值为x,则称x为吉利数.给定k,问最少要从A里面去掉多少个数,才能使k变为不吉利数. 解 ...
随机推荐
- WinSock IO模型 -- WSAEventSelect模型事件触发条件说明
FD_READ事件 l 调用WSAEventSelect函数时,如果当前有数据可读 l 有数据到达时,并且没有发送过FD_READ事件 l 调用recv/recvfrom函数后,仍然有数据可读时 ...
- [转] 强大的python字符串解析
1.python字符串通常有单引号('...').双引号("...").三引号("""...""")或('''...'' ...
- [转] linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些 信息至少包括进程ID,进程的终止状态,以及 ...
- HttpWebRequest get/post方法实现
get请求url #region GetHttp请求 /// <summary> /// GetHttp请求 /// </summary> /// <param name ...
- 第1章 你真的了解C#吗?
什么是C#? C#是由微软公司开发的一种面向对象且运行于.Net Framework之上的高级程序设计语言,发布于2000年6月. 什么是.Net Framework 我们可以这样去理解.Net Fr ...
- Html.Action、html.ActionLink与Url.Action的区别
1.html.ActionLink返回的指向指定controller.指定action的超链接标签<a>标签.如果没有指定controller,则默认为本页面对应的Controller. ...
- CSS3 2D转换
CSS3 转换 通过CSS3转换,我们能够对元素进行移动.缩放.转动.拉长或拉伸. 它如何工作? 转换是是元素改变形状.尺寸和位置的一种效果. 你可以使用2D或3D转换你的元素. 浏览器支持 属性 浏 ...
- java中保留几位小数
public class NumUtils { /** * 保留两位小数 * * @param d * @return */ public static String get2Wei(double d ...
- RTX管理器服务运行状态空白
A)打开RTX管理器安装目录下的bin文件夹,运行convert.bat 右键计算机——管理——服务——找到以RTX开头的服务,按RTX_ConfigCenter.RTX_HTTPServer. RT ...
- 1.Tomcat配置
1.启动 解压缩安装包后,点击startup.bat,保持控制台窗口开启 浏览器中输入http://localhost:8080 后看到启动界面则表示启动成功 点击shutdown.bat则关闭Tom ...