E - Remove Pairs
n有18,又每张卡牌只能取一次,所以考虑状压dp。容易知道当前回合没有卡牌的时候是必败
情况,将dp[0]初始化为0,又单张卡牌也是必败情况,我们遍历的时候将dp值先设为0,表示
默认都是必败的情况。然后考虑状态转移,如果可以转移且转移前的状态为必败,则当前状态
可以胜利(只要有一种转移前状态是必败的,当前状态就设置为可以胜利,即取max)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
//const ll P=2281701377;
const ll P=998244353;
int n;
int a[30],b[30];
int dp[1<<19];
void solve(){
cin>>n;
for(int i=0;i<n;i++){
int x,y;cin>>x>>y;
a[i]=x;b[i]=y;
}
dp[0]=0;
for(int i=1;i<(1<<n);i++){
vector<int> v;
//dp[i]=0;
for(int j=0;j<n;j++){
if((i>>j)&1){
v.push_back(j);
}
}
for(int j=0;j<v.size();j++){
for(int k=j+1;k<v.size();k++){
int x=v[j],y=v[k];
if(a[x]==a[y]||b[x]==b[y]){
dp[i]=max(dp[i],dp[i-(1<<x)-(1<<y)]^1);
}
}
}
}
if(dp[(1<<n)-1])
cout<<"Takahashi"<<endl;
else
cout<<"Aoki"<<endl;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
}
F - Useless for LIS
若一个位置可以出现在最长上升子序列,即以当前位置为尾的前缀最长上升子序列长度x,
和以当前位置为首的后缀最长上升子序列长度y,满足x+y等于完整序列最长上升子序列
长度+1。对于后者的求法可以考虑从后往前查找以当前位置为尾的最长下降子序列长度。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=4e5+10;
int n,a[N];
int b[N],c[N];
void solve(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
vector<int> v,vv;
int maxx=0;
for(int i=1;i<=n;i++){
b[i]=1;
if(v.size()==0){
v.push_back(a[i]);
}
else{
int p=lower_bound(v.begin(),
v.end(),a[i])-v.begin();
if(p==v.size()){
v.push_back(a[i]);
}
else{
v[p]=a[i];
}
b[i]=p+1;
}
maxx=max(maxx,b[i]);
}
for(int i=n;i>=1;i--){
c[i]=1;
if(vv.size()==0){
vv.push_back(a[i]);
}
else{
int p;
int l=0,r=vv.size()-1;
while(l<=r){
int mid=(l+r)/2;
if(vv[mid]>a[i]){
l=mid+1;
}
else{
r=mid-1;
}
//cout << "..." << endl;
}
p=l;
if(p==vv.size()){
vv.push_back(a[i]);
}
else{
vv[p]=a[i];
}
c[i]=p+1;
// cout << p << endl;
}
//cout << c[i] << endl;
}
vector<int> ans;
for(int i=1;i<=n;i++){
if(b[i]+c[i]==maxx+1){
ans.push_back(i);
}
}
cout << ans.size() << endl;
for(auto x:ans)
cout << x << ' ';
cout << "" << endl;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}