3280 easyfinding

3280 easyfinding

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题解

查看运行结果

题目描述 Description

给一个M 行N  列的01 矩阵,让你选出一些行 (不一定选出全部行)使得每一列都有 
且只有一个1。其中M<= 16,N<=300 。

输入描述 Input Description

输入含有多组数据。以文件结束符(eof )为结束。最多会有500 组。 
    输入之间会有梯度,也就是不是每组输入都是500 组。 
    对每组数据,第一行:两个由空格隔开的整数M 和N 。然后是M 行每行N  个等于0 
或者等于1 的整数,整数之间由空格隔开。

输出描述 Output Description

对每组数据输出一行,如果可以达到题中要求,输出Yes 否则输出No  。均不包括引号。

样例输入 Sample Input

3 3 
0 1 0 
0 0 1 
1 0 0 
4 4 
0 0 0 1 
1 0 0 0 
1 1 0 1 
0 1 0 0

样例输出 Sample Output

Yes 
No

数据范围及提示 Data Size & Hint

注意时间复杂度

分类标签 Tags 点此展开

搜索

第一次没读明白题目,任选几行组成(不一定连续)

用枚举做就AC了一个点

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int map[17][301];
int n,m;
void dfs(){
    int flag=0;
    for(int i=1;i<=m;i++)
        for(int j=i;j<=m;j++){
            for(int k=1;k<=n;k++){
                int num=map[j][k]-map[i-1][k];
                if(num!=1) break;
                if(k==m){flag=1;printf("Yes\n");return ;}
            }
        }
    if(!flag) printf("No\n");
}
int main(){
    while(scanf("%d%d",&m,&n)==2){
        memset(map,0,sizeof map);
        for(int i=1,x;i<=m;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&x),map[i][j]=map[i-1][j]+x;
            }
        }
        dfs();
    }
    return 0;
} 

正解AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 310
struct node{
    int vis[N];
}a[N];
int n,m,head,tail,flag;
int v[20][N];
int ok(int x){//验证
    for(int i=1;i<=m;i++)
        if(!a[x].vis[i])return 0;
    return 1;
}
void bfs(){
    while(head<=tail){//不明确第一个状态,so"<="
        if(head>10*n) return ;//防止死循环
        for(int i=1;i<=n;i++){
            ++tail;
            for(int j=1;j<=m;j++)//回溯
                a[tail].vis[j]=a[head].vis[j];
            int ff=0;
            for(int j=1;j<=v[i][0];j++)
                if(a[tail].vis[v[i][j]]){//有1 - 不满足
                    ff=1;break;
                }
            if(!ff){
                for(int j=1;j<=v[i][0];j++)
                    a[tail].vis[v[i][j]]=1;//更新vis
                if(ok(tail)){
                    flag=1;
                    printf("Yes\n");
                    return ;
                }
            }
            else
                tail--;//当前不满足,回溯
        }
        head++;
    }
}
int main(){
    while(scanf("%d%d",&n,&m)==2){
        memset(a,0,sizeof a);
        memset(v,0,sizeof v);
        for(int i=1,x;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&x);
                if(x) v[i][++v[i][0]]=j;//模拟动态数组,v[i][++v[i][0]]=j;记录第i行第v[i][0]个1的列号j
            }
        }
        head=0;tail=0;flag=0;
        bfs();
        if(!flag) printf("No\n");
    }
    return 0;
}
时间: 2024-07-29 09:17:03

3280 easyfinding的相关文章

【BZOJ】【3280】小R的烦恼

网络流/费用流 和软件开发那题基本相同,只是多加了一个“雇佣研究生”的限制:不同价格的研究生有不同的数量…… 那么只需加一个附加源点,对每一种研究生连边 S->ss 容量为l[i],费用为p[i]:再改由附加源点向每天的流入点(i+n)连边即可. 1 /************************************************************** 2 Problem: 3280 3 User: Tunix 4 Language: C++ 5 Result: Acce

POJ 3280 —— Cheapest Palindrome

题目:http://poj.org/problem?id=3280 经典的区间DP #include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; char s[2005], ch[2]; int cost[26]; int dp[2005][2005]; int main () { int n, m, c1, c2; scanf(

POJ 3280 Cheapest Palindrome DP题解

看到Palindrome的题目,首先想到的应该是中心问题,然后从中心出发,思考如何解决. DP问题一般是从更加小的问题转化到更加大的问题,然后是从地往上 bottom up地计算答案的. 能得出状态转移方程就好办了,本题的状态转移方程是: if (cowID[i] == cow{j]) tbl[id][i] = tbl[id][i+1];//相等的时候无需改动 else tbl[id][i] = min(tbl[!id][i+1] + cost[cowID[i]-'a'], tbl[!id][i

BZOJ 3280: 小R的烦恼 &amp; BZOJ 1221: [HNOI2001] 软件开发

3280: 小R的烦恼 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 399  Solved: 200[Submit][Status][Discuss] Description 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题. 问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共持续n天,第i天需要a[i]个研究生来给他搬砖.研究生毕竟也是人,

(中等) POJ 3280 Cheapest Palindrome,DP。

Description Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag's contents are

POJ 3280:Cheapest Palindrome 区间DP好题

Cheapest Palindrome 题目链接: http://poj.org/problem?id=3280 题意: 给出一个只由小写字母组成的串,可以添加或删除一些字母(添加和删除都需要花费且花费不同),求将这个串改变成一个回文串的最小花费. 题解: 设dp[i][j]是将区间[i,j]改变成回文串的最小花费,则两种情况 ①显而易见,当s[i]==s[j]时,dp[i][j]=dp[i+1][j-1] ②当s[i]!=s[j]时,dp[i][j]有四种可能的取值,区间 [i,j-1] 删除

POJ 3280 Cheapest Palindrome(DP)

题目链接 题意 :给你一个字符串,让你删除或添加某些字母让这个字符串变成回文串,删除或添加某个字母要付出相应的代价,问你变成回文所需要的最小的代价是多少. 思路 :DP[i][j]代表的是 i 到 j 这一段位置变成回文所需的最小的代价. 1 //3280 2 #include <stdio.h> 3 #include <string.h> 4 #include <iostream> 5 6 using namespace std ; 7 8 char sh[2100]

bzoj 3280: 小R的烦恼(费用流)

3280: 小R的烦恼 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 300  Solved: 154 [Submit][Status][Discuss] Description 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题. 问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共持续n天,第i天需要a[i]个研究生来给他搬砖.研究生毕竟也是

POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思路:比较简单的区间DP,令dp[i][j]表示使[i,j]回文的最小花费.则得到状态转移方程: dp[i][j]=min(dp[i][j],min(add[str[i]-'a'],del[str[i]-'a'])+dp[i+1][j]); dp[i][j]=min(dp[i][j],min(add[