#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
int n,k;
const int N = 1<<10;
int dp[12][150][N];
vector<int>state;
vector<int>head[N];
bool check(int x){
for(int i=0;i<n;i++){
if( (x>>i&1)&&( x>>i+1 &1) )return 0;
}
return 1;
}
int count(int x){
int ans=0;
for(int i=0;i<n;i++){
ans+=((x>>i )&1);
}
return ans;
}
signed main(){
cin>>n>>k;
for(int i=0;i<1<<n;i++){
if(check(i))state.push_back(i);
}
for(int i=0;i<state.size();i++){
for(int j=0;j<state.size();j++){
int a=state[i],b=state[j];
if((a&b)==0&&check(a|b)){
head[i].push_back(j);
}
}
}
dp[0][0][0]=1;
for(int i=1;i<=n+1;i++){
for(int j=0;j<=k;j++){
for(int b=0;b<state.size();b++){
for(int a:head[b]){
int c=count(state[a]);
if(j>=c){
dp[i][j][b]+=dp[i-1][j-c][a];
}
}
}
}
}
cout<<dp[n+1][k][0];
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1<<12;
const int mod=1e8;
int m,n;
int dp[15][N];
int g[N];
vector<int>state;
vector<int>head[N];
bool check(int s){
for(int i=0;i<n;i++){
if((s>>i&1)&&(s>>i+1&1))return 0;
}
return 1;
}
int main(){
cin>>m>>n;
for(int i=0;i<1<<n;i++){
if(check(i))state.push_back(i);
}
for(int i=1;i<=m;i++){
for(int j=0;j<n;j++){
//cin>>mp[i][j];
int t;
cin>>t;
g[i]+=!t<<j;
}
}
for(int i=0;i<state.size();i++){
for(int j=0;j<state.size();j++){
int a=state[i];
int b=state[j];
if(a&b)continue;
head[i].push_back(j);
}
}
dp[0][0]=1;
for(int i=1;i<=m+1;i++){
for(int a=0;a<state.size();a++){
for(int b:head[a]){
if(state[a]&g[i])continue;
dp[i][a]+=dp[i-1][b];
}
}
}
cout<<dp[m+1][0]%mod;
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110 , M = 59055;
int n , m;
int p[12] = {0 , 1 , 3 , 9 , 27 , 81 , 243 , 729 , 2187 , 6561 , 19683,59049};
int f[N][M];
int v[12];
char map[N][12];
void operate(int row ,int last){
for(int i = 0 ; i < m ; i++ , last /= 3)
if(last % 3 == 2)v[i + 1] = 1;
else if(last % 3 == 1)v[i + 1] = 0;
else if(map[row][i + 1] == 'H')v[i + 1] = 0;
else v[i + 1] = 2;
}
void dfs(int row ,int col , int last ,int now ,int cnt){
if(col > m)
{
f[row + 1][now] = max(f[row + 1][now] , f[row][last] + cnt);
return ;
}
if(v[col] == 2)
{
int v1 = v[col + 1], v2 = v[col + 2];
if(v[col + 1] == 2)v[col + 1] = 0;
if(v[col + 2] == 2)v[col + 2] = 0;
dfs(row , col + 1 , last , now + 2 * p[col], cnt + 1);
v[col + 1] = v1, v[col + 2] = v2;
}
if(v[col] == 1)dfs(row , col + 1 , last,now + p[col] , cnt);
if(v[col] == 2 || v[col] == 0)dfs(row , col + 1 , last,now , cnt);
}
int main(){
cin >> n >> m ;
for (int i = 1; i <= n; i++) scanf("%s", map[i] + 1);
memset(f , -1 , sizeof(f));
f[0][0] = 0;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < p[11] ; j++)
{
if(f[i][j] < 0)continue;
operate(i + 1 , j);
dfs(i , 1 , j , 0,0);
}
}
int ans = 0;
for (int j = 0; j < p[11]; j++) ans = max(ans, f[n][j]);
cout << ans << endl;
return 0;
}
作者:MrLuo
链接:https://www.acwing.com/solution/content/18944/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#include<iostream>
#include <iostream>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
int m,n;
const int S=1<<10;
int f[2][S][S],g[S],cnt[S];
vector<int>state;
bool check(int x){
if(x&x<<1)return 0;
if(x&x<<2)return 0;
return 1;
}
int count(int x){
int res=0;
for(int i=0;i<n;i++){
res+=x>>i&1;
}
return res;
}
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=0;j<n;j++){
char c;
cin>>c;
if(c=='H')g[i]+=1<<j;
}
}
for(int i=0;i<1<<n;i++){
if(check(i)){
state.push_back(i);
cnt[i]=count(i);
}
}
for(int i=1;i<=m+2;i++){
for(int j=0;j<state.size();j++){
for(int k=0;k<state.size();k++){
for(int u=0;u<state.size();u++){
int a=state[j];
int b=state[k];
int c=state[u];
if(a&b||a&c||b&c)continue;
if(a&g[i])continue;
f[i&1][k][j]=max(f[i&1][k][j],f[i-1&1][u][k]+cnt[a]);
}
}
}
}
cout<<f[m+2&1][0][0];
}
noip他们喜欢将一些知识点全都砸在一起考
dfs出错代码
#include <iostream>
#include <cstring>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<double, double> PDD;
int ans=0x3f3f3f3f;
PDD p[110];
int line[110][110];
int n,m;
int t;
bool vis[100][100];
bool check(int state){
for(int i=1;i<=n;i++){
if(state<<i &0)return 0;
}
return 1;
}
bool cmp(double x,double y){
if(abs(x-y)<1e-6)return 1;
return 0;
}
int count(int x){
int res=0;
for(int i=1;i<=n;i++){
res+=x>>i&1;
}
return res;
}
void dfs(int state,int cnt){
// cout<<count(state)<<endl;
cout<<"cnt="<<cnt<<endl;
if(count(state)==n&&cnt!=0){
ans=min(ans,cnt);
return;
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n+1;j++){
//if(i==j)continue;
if(!vis[i][j]){
vis[i][j]=1;
//cout<<"cnt="<<cnt<<endl;
dfs(state|line[i][j],cnt+1);
vis[i][j]=0;
//cout<<"cnt="<<cnt;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
ans=0x3f3f3f3f;
memset(vis,0,sizeof vis);
memset(line,0,sizeof line);
cin>>n>>m;
if(n==1){
cout<<"1"<<endl;
continue;
}
for(int i=1;i<=n;i++){
cin>>p[i].x>>p[i].y;
}
for(int i=1;i<n;i++){
line[i][i]+=1<<i;
for(int j=i+1;j<=n;j++){
double x1=p[i].x,y1=p[i].y;
double x2=p[j].x,y2=p[j].y;
double a=((y1/x1)-(y2/x2))/(x1-x2);
if(a>0)continue;//这个点要想好,可以随着题意有灵活的变化
//比如如果我说对面有很牛逼的空防,我们只能发射往下迂回的导弹
double b=y1/x1-a*x1;
int state=0;
for(int k=1;k<=n;k++){
//cout<<"state="<<state<<endl;
if( cmp(p[k].y,a*p[k].x*p[k].x+b*p[k].x) )state+=1<<k;
//至少穿过两个点,也有可能穿过别的点
}
line[i][j]=state;
line[j][i]=state;
//cout<<"line["<<i<<"]["<<j<<"]="<<line[i][j]<<endl;
}
}
//接下来就是用状态转移方程进行优化的区间重复覆盖问题了
dfs(0,0);
cout<<ans<<endl;
}
}
AK代码
#include<bits/stdc++.h>
#define x first
#define y second
#define eps 1e-12
using namespace std;
typedef pair<double, double> PDD;
PDD p[18];
int line[18][18],f[1<<18],n,m,t;
int cmp(double x, double y)
{
if (fabs(x - y) < eps) return 0;
if (x < y) return -1;
return 1;
}
int main(){
cin>>t;
while(t--){
memset(line ,0,sizeof line);
//memset(p,0,sizeof p);
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>p[i].x>>p[i].y;
}
for(int i=0;i<n;i++){
line[i][i]=1<<i;
for(int j=0;j<n;j++){
if(i==j)continue;
double x1=p[i].x,y1=p[i].y;
double x2=p[j].x,y2=p[j].y;
double a=(y1/x1-y2/x2)/(x1-x2);
//if(a-eps>=0)continue;
if(cmp(a,0)>=0)continue;
double b=y1/x1-a*x1;
int state=0;
for(int k=0;k<n;k++){
double xx=p[k].x;
double y=p[k].y;
double yy=a*xx*xx+b*xx;
//if(yy-eps < y < yy+eps)state|=1<<k;
if(!cmp(y,yy))state+=1<<k;
}
line[i][j]=state;
line[j][i]=state;
}
}
memset(f,0x3f,sizeof f);
//预处理完毕,现在用状态dp来优化
f[0]=0;
for(int i=0;i<1<<n;i++){
int x=0;
for(int j=0;j<n;j++){
if(! (i>>j&1) ){
x=j;
break;
}
}
for(int j=0;j<n;j++){
f[i|line[x][j] ]=min(f[i|line[x][j]],f[i]+1);
}
}
cout<<f[(1<<n)-1]<<endl;
}
}