瞬间感觉自己的c++实践还真是不够啊,长知识了!
题意:有k个盒子,每个盒子有n维,问最多能嵌套多少。
方法一:对盒子按维度排序,利用c++类,STL
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int k,n;
struct Box
{
int id;
vector<int> a;
bool operator<=(const Box &b) const
{
return (lexicographical_compare(a.begin(), a.end(),
b.a.begin(), b.a.end()));
}
bool cmp(const Box &b) const
{
return (mismatch(a.begin(), a.end(),
b.a.begin(), greater<int>()).first == a.end());
}
};
int main()
{
//freopen("in.txt","r",stdin);
int x;
while(cin>>k>>n)
{
vector<Box> box(k);
for(int i=0; i<k; i++)
{
box[i].id=i;
for(int j=0; j<n; j++)
{
cin>>x;
box[i].a.push_back(x);
}
sort(box[i].a.begin(),box[i].a.end(),greater<int>());
}
sort(box.begin(),box.end(),less_equal<Box>() );
vector<int> verpre(k,-1),vermax(k,0);
int nmax=0;
for(int i=0; i<k; i++)
{
for(int j=0; j<i; j++)
if(box[i].cmp(box[j])&&(vermax[i]<vermax[j]||vermax[i]==0))
{
//cout<<1;
vermax[i]=vermax[j];
verpre[i]=j;
}
if(++vermax[i]>vermax[nmax])
nmax=i;
}
for(vermax.clear(); nmax!=-1; nmax=verpre[nmax])
vermax.push_back(nmax);
//DP(box);
vector<int>::reverse_iterator ri = vermax.rbegin();
cout << vermax.size() << '\n' << box[*ri++].id + 1;
for (; ri != vermax.rend(); ++ri)
{
cout << ' ' << box[*ri].id + 1;
}
cout << endl;
}
return 0;
}
总结一下学到的东西。
1.lexicographical_compare(
InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 );
安字典序比较两个序列
2.mismatch(first1,last1,first2,compare);求出两个序列相异的第一个元素
它的返回值是一个pair,pair的first和second分别是第一次两个元素不同时,分别记录它们的指向的元素,如果我有两个容器都是vector <int> A,B.那么pair应该这么写:pair<vector <int>::iterator,vector <int> ::iterator>;
3.less_equal<BOX>()
跟less<int>一样,这个只不过是包含了等于的情况。
4.还有就是重载操作符的时候(针对codeblocks)
成员函数参数前要加const,并且函数要声明称const。
友元函数参数要加const。
bool operator<=(const Box &b) const
{
return (lexicographical_compare(a.begin(), a.end(),
b.a.begin(), b.a.end()));
}
这个const的问题,搞不太明白,以后还是加上吧,不加编译都通不过
方法二:记忆化动态规划,以前没写过,学习一下。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int k,n;
int box[35][15];
int route[35],map[35];
bool fun(int a[],int b[])
{
for(int i=0; i<n; i++)
if(a[i]>=b[i])
return false;
return true;
}
int dp(int pos)
{
if(map[pos]>0)
return map[pos];
for(int i=0; i<k; i++)
{
if(i==pos)
continue;
if(fun(box[pos],box[i]))
{
int res=dp(i);
if(map[pos]<res+1)//更新此位置上的最大值
{
map[pos]=res+1;
route[pos]=i;//保存可以达到最大的下一个位置
}
}
}
map[pos]=max(map[pos],1);
return map[pos];
}
int main()
{
//freopen("in.txt","r",stdin);
while(cin>>k>>n)
{
memset(box,0,sizeof(box));
for(int i=0; i<k; i++)
{
for(int j=0; j<n; j++)
cin>>box[i][j];
sort(box[i],box[i]+n);
}
memset(route,0,sizeof(route));
memset(map,0,sizeof(map));
int temp=0,imax=0,pos=0;
for(int i=0; i<k; i++)
{
temp=dp(i);
if(imax<temp)
{
imax=temp;
pos=i;//记录最后一个位置
}
}
cout<<imax<<endl;
cout<<pos+1;
for(int i=1; i<=imax-1; i++)
{
cout<<' '<<route[pos]+1;
pos=route[pos];
}
cout<<endl;
}
return 0;
}