题目描述
我们称一个矩阵是下降矩阵,当且仅当,矩阵的每一列都是严格下降的。很显然,这个要求很苛刻,大多数矩阵都无法满足。但是显然如果消去一些行,一定可以使得这个矩阵变成下降矩阵。
现在给出一个n行m列的矩阵,请你求出最少消去多少行,可以使得这个矩阵变为下降矩阵。
现在给出一个n行m列的矩阵,请你求出最少消去多少行,可以使得这个矩阵变为下降矩阵。
输入
输入第一行包含两个正整数n,m分别表示矩阵的行数和列数。(1<=n,m<=300)
接下来n行,每行有m个数,中间用空格隔开,每个数都小于2^31.
接下来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 吗?
但是 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
然后是 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;
}