插头dp从入门到不会
POJ 2411 Mondriaan's Dream
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>
using namespace std;
#define ll long long
const int maxn=12;
ll dp[maxn*maxn+50][(1<<maxn)+50];
int main(){
int n,m;
while(scanf("%d %d",&n,&m)==2&&(n||m)){
if(n<m)swap(n,m);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
int st=1<<(m+1);
int cot=0;
int flag;
int ne;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
//保证合法递推
for(int s=0;s<st;s++)if(dp[cot][s]>0){
flag=(s>>m)|(s&1);//获取位置位置
ne=(s<<1)&(~3);//右移并空出最后两位
ne=ne&((1<<(m+1))-1);//保留m位信息
if(!flag){
if(i!=n-1)dp[cot+1][ne|2]+=dp[cot][s];
if(j!=m-1&&((s>>(m-1))&1)==0)dp[cot+1][ne|1]+=dp[cot][s];
}
else dp[cot+1][ne]+=dp[cot][s];
}
cot++;
}
}
printf("%lld\n",dp[cot][0]);
}
return 0;
}
HDU 1565 方格取数(1)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>
using namespace std;
#define ll long long
const int maxn=25;
ll grap[maxn][maxn];
ll dp[2][(1<<20)+50];
int main(){
int n;
int p;
while(scanf("%d",&n)==1){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%lld",&grap[i][j]);
}
}
p=0;
memset(dp,-1,sizeof(dp));
dp[p][0]=0;
int st=1<<n;
ll ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int s=0;s<st;s++)if(dp[p][s]!=-1){
if(s&(1<<j))dp[p^1][s^(1<<j)]=max(dp[p][s],dp[p^1][s^(1<<j)]);
else if(j!=0&&(s&(1<<(j-1))))dp[p^1][s^(1<<j)]=max(dp[p][s],dp[p^1][s^(1<<j)]);
else dp[p^1][s^(1<<j)]=max(dp[p][s]+grap[i][j],dp[p^1][s^(1<<j)]);
dp[p^1][s&(~(1<<j))]=max(dp[p][s],dp[p^1][s&(~(1<<j))]);
}
p^=1;
}
}
for(int s=0;s<st;s++)ans=max(ans,dp[p][s]);
printf("%lld\n",ans);
}
return 0;
}
HDU 2167 Pebbles
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>
using namespace std;
#define ll long long
const int maxn=16;
int dp[2][(1<<maxn)+50];
int num[maxn+5][maxn+5];
/*int n;
int m;
bool read(){
n=0;
m=0;
char ch;
int cot=0;
num[n][m]=0;
while(cot<2){
ch=getchar();
if(ch>='0'&&ch<='9'){
cot=0;
num[n][m]=num[n][m]*10+ch-'0';
}
else if(ch==' '){
cot=0;
num[n][++m]=0;
}
else if(ch=='\n'){
if(!cot)n++;
m=0;
num[n][m]=0;
cot++;
}
else if(ch==EOF){
if(!cot)n++;
return false;
}
}
return true;
}*/
char s[maxn*maxn];
int main(){
//printf("%d\n",sizeof(num)+sizeof(dp));
//freopen("in.txt","r",stdin);
int ne;
int flag;
while(true){
int n=16;
int t=0;
int st=1<<(n+1);
memset(dp,-1,sizeof(dp));
int p=0;
dp[0][0]=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
char ch;
if(scanf("%d%c",&num[i][j],&ch)==-1)return 0;
t++;
if(ch=='\n'&&n==16)n=t;
}
}
st=1<<(n+1);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int s=0;s<st;s++)if(dp[p][s]!=-1){
if(j==0)flag=(s>>(n-2))&3;
else if(j==n-1)flag=(s>>(n-1))|(s&1);
else flag=(s>>(n-2))|(s&1);//获取邻格信息
ne=(s<<1)&((1<<(n+1))-1);
if(!flag)dp[p^1][ne|1]=max(dp[p^1][ne|1],dp[p][s]+num[i][j]);
dp[p^1][ne]=max(dp[p^1][ne],dp[p][s]);
}
memset(dp[p],-1,sizeof(dp[p]));
p^=1;
}
}
int ans=0;
for(int s=0;s<st;s++)ans=max(dp[p][s],ans);
printf("%d\n",ans);
}
return 0;
}
HDU 1693 Eat the Trees
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>
using namespace std;
#define ll long long
const int maxn=11;
ll dp[2][532000];
int num[maxn+5][maxn+5];
int pow3[maxn+5];
int pos[maxn+5];
int tmp[maxn+5];
int getstate(int pos[],int m){
int res=0;
for(int i=0;i<=m;i++)
res+=pos[i]*pow3[i];
return res;
}
int main(){
pow3[0]=1;
for(int i=1;i<=maxn+2;i++)pow3[i]=pow3[i-1]*3;
int t;
int n,m;
scanf("%d",&t);
for(int kase=1;kase<=t;kase++){
scanf("%d %d",&n,&m);
//if(n<m)swap(n,m);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&num[i][j]);
int st=pow3[m+1];
int L,T;
int p=0;
dp[0][0]=1;
for(int i=0;i<n;i++){
for(int s=0;s<st;s++)if(dp[p][s]){
int ss=s;
for(int k=1;k<=m;k++){
tmp[k]=ss%3;
ss/=3;
}
//if(ss!=0)continue;
tmp[0]=0;
dp[p^1][getstate(tmp,m)]=dp[p][s];
}
memset(dp[p],0,sizeof(dp[p]));
p^=1;
for(int j=0;j<m;j++){
for(int s=0;s<st;s++)if(dp[p][s]){
int ss=s;
for(int k=0;k<=m;k++){
pos[k]=ss%3;
ss/=3;
}
if(num[i][j]==0){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=tmp[j+1]=0;
dp[p^1][getstate(tmp,m)]+=dp[p][s];
continue;
}
L=j;
T=j+1;
if(pos[L]==0&&pos[T]==0&&j!=m-1&&i!=n-1&&num[i+1][j]&&num[i][j+1]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=1;tmp[j+1]=2;
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
if(pos[L]&&pos[T]==0){
if(i!=n-1&&num[i+1][j]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=pos[L];tmp[j+1]=0;
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
if(j!=m-1&&num[i][j+1]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=0;tmp[j+1]=pos[L];
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
}
if(pos[L]==0&&pos[T]){
if(j!=m-1&&num[i][j+1]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=0;tmp[j+1]=pos[T];
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
if(i!=n-1&&num[i+1][j]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=pos[T];tmp[j+1]=0;
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
}
if(pos[L]&&pos[T]){
if(pos[L]!=pos[T]){
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=tmp[j+1]=0;
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
else {
memcpy(tmp,pos,sizeof(tmp));
tmp[j]=tmp[j+1]=0;
int cot=0;
if(pos[j+1]==1)
for(int l=j+2;l<=m;l++){
if(pos[l]==1)cot++;
else if(pos[l]==2){
if(cot--==0)tmp[l]=1;
}
}
else if(pos[j+1]==2)
for(int l=j-1;l>=0;l--){
if(pos[l]==2)cot++;
else if(pos[l]==1){
if(cot--==0)tmp[l]=2;
}
}
dp[p^1][getstate(tmp,m)]+=dp[p][s];
}
}
}
memset(dp[p],0,sizeof(dp[p]));
p^=1;
/*for(int s=0;s<st;s++){
printf("%d ",dp[p][s]);
}
puts("");*/
}
}
printf("Case %d: There are %lld ways to eat the trees.\n",kase,dp[p][0]);
}
return 0;
}
URAL 1519 Formula 1
...待填
URAL 1520 Empire Strikes Back
...待填
FZU 1977 Pandora adventure
...待填
HDU 1964 Pipes
...待填
HDU 3377 Plan
...待填
POJ 1739 Tony's Tour
...待填
POJ 3133 Manhattan Wiring
...待填
ZOJ 3466 The Hive II
...待填
ZOJ 3256 Tour in the Castle
...待填
ZOJ 3213 Beautiful Meadow
...待填
HDU 4285 circuits
...待填