2019ccpc-HN省赛-A/I

                 A.最大下降矩阵

时间限制: 1 Sec  内存限制: 512 MB
提交: 508  解决: 107
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述
我们称一个矩阵是下降矩阵,当且仅当,矩阵的每一列都是严格下降的。很显然,这个要求很苛刻,大多数矩阵都无法满足。但是显然如果消去一些行,一定可以使得这个矩阵变成下降矩阵。

现在给出一个n行m列的矩阵,请你求出最少消去多少行,可以使得这个矩阵变为下降矩阵。
输入
输入第一行包含两个正整数n,m分别表示矩阵的行数和列数。(1<=n,m<=300)
接下来n行,每行有m个数,中间用空格隔开,每个数都小于2^31.
输出
输出仅包含一个整数,即最少消去的行数。
样例输入 Copy
1 3
1 2 3 
样例输出 Copy
0

 

 

    把每一行元素看作一个向量,或者说一个"行元素"。题目要求的就是对于N个向量来说的最长的严格下降子序列长度,然后用N减去这个严格下降子序列长度就是答案了。方法与求LIS类似。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int N,M;
 5 int v[330][330];
 6 int f[330]={0};
 7 bool cmp(int di,int dj){
 8     for(int i=1;i<=M;++i){
 9         if(v[di][i] <= v[dj][i] ) return 0;
10     }return 1;
11 }
12 int main()
13 {
14     cin>>N>>M;
15     for(int i=1;i<=N;++i)
16     for(int j=1;j<=M;++j)
17     cin>>v[i][j];
18     f[1]=1;
19     int ans=1;
20     for(int i=2;i<=N;++i){
21         f[i]=1;
22         for(int j=1;j<i;++j){
23             if(cmp(j,i)){
24                 f[i]=max(f[i],f[j]+1);
25             }
26         }
27         ans=max(ans,f[i]);
28     }
29     cout<<N-ans<<endl;
30     return 0;
31 }

问题 I: Childhood dream

时间限制: 1 Sec  内存限制: 256 MB
提交: 63  解决: 18
[提交] [状态] [讨论版] [命题人:zhd]
题目描述
你童年时期就有一个梦想,想要加入 ACM(Association of Calculation and Magic),今天,这个机会终于 来了。  
但是 ACM 只想要哪些天赋异禀的人, 比如像 tourist,他们给了你一道题来检测你是否足够机智。  
猜一个长度为 m 数字串,总共有 n 个提示串,解释如下: 
 8640 0A2B  
A 前面的数字说明与答案相比,有多少个位置上的数字是相同的。 B 前面的数字说明与答案相比,有多 少个数字是相同的,但是位置不一样。 
 0 A 就表示给出的串没有任何位置和答案是相同的。 2 B 就表示给出的串中有两个数字和答案相同,但 是位置不一样。  
所以,对于上面那个提示串 6457 是一个合理的答案,但是 1234 并不是。  
现在给你 N(N<=100) 个提示串(如上所示),你需要去找到一个数字串来符合每一个提示串的要求。 
提示串中的每个数字都是不同的,即一个串中不会存在相同的数字。  
你能解决这个问题并加入 ACM 吗?  
输入
第一行两个数字,n(n<=100) 和 m(m<=9), 提示串的数量以及目标字符串的长度。  
然后是 n 行,每行的格式如下:  
s x y  
s 是提示串,x 是 A 前的数字,y 是 B 前的数字,等同于:  
s xAyB  
输出
一行,目标串。
数据保证答案唯一。 
样例输入 Copy
6 4
5164 3 0
5174 3 0
5194 3 0
5124 3 0
5134 3 0
5104 3 0
样例输出 Copy
5184

暴力搜索,由于不可行的情况很多,减枝会减去很多方案,所以直接搜完事。
#include<bits/stdc++.h>
using namespace std;

char str[115][15]; 
int A[115],B[115],tot[115][10];
int N,M;
int c[15];
bool ok=0;
bool check(int n,int type){
    for(int i=1;i<=N;++i){
        int _A=0,_B=0;
        for(int j=0;j<n-1;++j){
            if(str[i][j]-'0' == c[j+1]){
                _A++;
            }
            else{
                if(tot[i][c[j+1]]){
                    _B++;
                }
            }
        }
        if(type==0 &&(_A>A[i]  || _B>B[i] )) return 0;
        if(type==1 &&(_A!=A[i] || _B!=B[i])) return 0;
    }
    return 1;
}
void dfs(int u){
    if(ok)return;
    if(!check(u,0)){
        return;
    }
    if(u==M+1){
        if(check(M+1,1)){
            ok=1;
            for(int i=1;i<=M;++i)cout<<c[i];cout<<endl;
        }
        return;
    }
    else{
        for(int i=0;i<10;++i){
            c[u]=i;
            dfs(u+1);
        }
    }
}
int main()
{
    cin>>N>>M;
    for(int i=1;i<=N;++i){
        cin>>str[i]>>A[i]>>B[i];
    }
    for(int i=1;i<=N;++i){
        for(int j=0;j<M;++j){
            tot[i][str[i][j]-'0']++;
        }
    }
    dfs(1);
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/zzqc/p/10704290.html