uva 11464 Even Parity 递推
来源:互联网 发布:js explode 编辑:程序博客网 时间:2024/06/06 02:21
题目链接:
https://uva.onlinejudge.org/external/114/11464.pdf
首先可以知道每个数字,可以改变或不改变(当然 依题意 ,是0才能够改变)
这样暴力枚举会超时。
那么既然暴力枚举不行,就证明有非暴力的解决方法:
1. 贪心或规律,(直接找到解题策略)认为的找出改变方法,此策略对所有情况均适用。
2.找出部分规律 ,定下解答的一部分 ,然后计算其余可变化的部分,枚举或有效利用各种算法,减少时间复杂度。
两者均比直接暴力时间要少。
对于一个题目,首先有直接求解法,比如说先直接分步,或是先直接分类,然后加以计算。
还有间接求解法,比如说我想知道f[n]的值,却不知道怎样直接求出 f[n], 但我知道f[1]的值,也知道f[i]怎么推出f[i+1],那么我可以从f[1]步步递推,
直到求出f[n]。
反观自己,过去对于递推的理解实在很狭隘,不知道递推的好处,也不知道怎么用递推:
首先,分析一个问题,一定要充分抓住已知条件,一个题目里面变化的东西有很多,但是也有不变的东西,
先要确定不变的是什么,(排序规则 ,选取规则 ,时间长短...)
当初想这个问题,就是使劲去找到底什么不变?选择点的方法?还是有什么数量规律?翻来覆去就是弄不出来。
因为,如果能找出定的信息或规律,一定是要有用的,可以利用求出答案的。
第二,
递推找到起点很重要,知道了dp[0]=1(计数DP),才可能推出后面的,而且这个dp[0]=1是个起点,什么不选的情况就是1种。
因为平时递推的起点很显然,没有注意过,而这个题很隐蔽,所以让人想不到递推。
第三,
递推关系很重要,
这个题的条件其实可以转化为递推关系: 假如某个点的上、左、右已经确定了,那么它下个点就确定了。
(这就是递推关系)
证明我们善于要分析出隐蔽的递推关系
这个题也是,看不出有递推关系,压根想不到递推。 (这个递推关系就是个定的,不变的规律)
对于此题,充分利用递推关系,确定递推起点,则可得解。
这个题的解法:首先枚举第一行的情况,然后根据第一行,可以推出第二行,之后根据第二行推出第三行,(证明递推的顺序很重要)
直到推出第n行。
属于解法2.
综上:对于一个问题,先要找到问题的大致方向,是暴力枚举,还是人为想出特定解法,还是充分利用 已知条件(还不足以求出答案) 再加上高效算法。
如果想用递推解决问题,那么先要确立递推关系(状态转移方程),找到隐蔽的递推起点,然后决定递推顺序,
(之所以这样,因为很多题目这三者实在太显然,让我们忽略了它们的重要性)。
int a[maxn][maxn];int b[maxn][maxn];int n,ans;bool ok;int kase;int dir[4][2]={{-1,0},{0,-1},{0,+1},{+1,0} };int f(int y,int x){ int ans=0; for(int i=0;i<3;i++) { int ty=y+dir[i][0]; int tx=x+dir[i][1]; ans+=b[ty][tx]; } return ans;}int f2(int y,int x){ int ans=0; for(int i=0;i<4;i++) { int ty=y+dir[i][0]; int tx=x+dir[i][1]; ans+=b[ty][tx]; } return ans;}int check( ){ int cnt=0; for(int i=2;i<=n;i++) { for(int j=1;j<=n;j++) { int tmp=f(i-1,j); if( (tmp%2) !=a[i][j]) { if(a[i][j]==1) {cnt=-1;return cnt;} cnt++; b[i][j]=1; } else { b[i][j]=a[i][j]; } } } /*我担心这样推出后,最后一排的没有验证是否符合, 所以单独拿出来验证一遍,书中没有验证,我还没想清为什么*/ for(int i=1;i<=n;i++) { if(f2(n,i)%2) {cnt=-1;break;} } return cnt;}void dfs(int step,int num){ if(step==n+1) { int tmp; if( ( tmp=check( ) )!=-1 ) { ans=min(ans,tmp+num); } return; } if(!a[1][step]) { b[1][step]=1; dfs(step+1,num+1); } b[1][step]=a[1][step]; dfs(step+1,num);}int main(){ int T;kase=0; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); } memset(b,0,sizeof b); //这句话掉了就错,虽然我认为不影响,但要注意。 ans=INF; dfs(1,0); if(ans==INF) ans=-1; printf("Case %d: %d\n",++kase,ans); } return 0;}
头文件:
#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)#define lson num<<1,le,mid#define rson num<<1|1,mid+1,ri#define MID int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)#define mk make_pair#define _f first#define _s secondusing namespace std;const int INF =0x3f3f3f3f;const int maxn= 20 ;//const int maxm= ;//const int INF= ;typedef long long ll;//const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);//by yskysker123
- UVA - 11464 Even Parity 枚举+递推
- uva 11464 Even Parity 递推
- uva - 11464 - Even Parity(部分枚举,递推)
- uva 11464 - Even Parity (枚举+递推)
- UVA 11464 Even Parity(枚举递推)
- UVA 11464 - Even Parity
- uva 11464 - Even Parity
- Uva-11464-Even Parity
- uva 11464Even Parity
- Uva 11464 - Even Parity
- Uva 11464 - Even Parity
- uva 11464 - Even Parity
- UVA 11464 Even Parity
- UVA 11464 Even Parity
- Even Parity UVA 11464
- UVA - 11464 Even Parity
- UVA - 11464 Even Parity
- UVa:11464 Even Parity
- mongo导入导出
- Linux 命令
- AIX系统删除不需要的用户和组
- Java多线程实现同时进行小球的自由落体与平抛
- 表单校验的值valid、invalid、pristine和dirty
- uva 11464 Even Parity 递推
- PHP开发规范PSR
- 制作一个可拖动的html对话框
- 如何在mac本上安装android sdk
- Android 设置 横屏 竖屏
- jsp笔记
- 从AIDL开始谈Android进程间Binder通信机制
- HTML 水平对齐方式总结
- 支持向量机: Maximum Margin Classifier