状态压缩+dfs+背包
状态压缩dp
状态压缩dp就是用二进制数字来表示状态,通过遍历所有状态确定答案,时间复杂度为o(nn2^n),通常只能用来解数据范围小于等于21的。
P1433 吃奶酪
#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
/*不要被困在一种思路中
*/
//dp i j 表示在i状态下位于j位跑动的最小距离
double dis[20][20],ans=0xffffffff,dp[35000][20],r[20],c[20];double getdis(int i,int j){return sqrt((r[i]-r[j])*(r[i]-r[j])+(c[i]-c[j])*(c[i]-c[j]));
}int main()
{int n;cin>>n;memset(dp,127,sizeof(dp));for(int i=1; i<=n; i++)cin>>r[i]>>c[i];for(int i=0; i<=n; i++)for(int j=i; j<=n; j++)dis[i][j]=getdis(i,j),dis[j][i]=dis[i][j];for(int i=1; i<=n; i++){dp[1<<(i-1)][i]=dis[0][i];}for(int i=1; i<=(1<<n)-1; i++){for(int j=1; j<=n; j++){if(i&(1<<(j-1))==0)continue;for(int k=1; k<=n; k++){if(j==k)continue;if(i&(1<<(k-1))==0)continue;dp[i][j]=min(dp[i][j],dp[i&~(1<<(j-1))][k]+dis[j][k]);}}}for(int i=1; i<=n; i++){ans=min(ans,dp[(1<<n)-1][i]);}printf("%.2lf",ans);return 0;
}
这个题还可以使用dfs+状态压缩优化来解,可以通过记录状态来做出一个记忆化搜索。当通过的位置确定了,无论是怎么走的,当前所走的最小步数也就确定了。
#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
double bestv=0xffffffff;
int n;
double dp[65000][20];
map<pair<double,double>,int> visit;
pair<double,double> a[20];double getdis(pair<double,double> p1,pair<double,double> p2){return sqrt(pow(p1.first-p2.first,2)+pow(p1.second-p2.second,2));
}void dfs(int i,double now,int bi,pair<double,double> p){if(i==n){bestv=min(bestv,now);return;}for(int j=1; j<=n; j++){//bt记录当前状态int bt=bi|(int)pow(2,j-1);if(visit.find(a[j])->second)continue;if(now+getdis(p,a[j])>=bestv)continue;//剪枝if(now+getdis(p,a[j]) > dp[bt][j])continue;//更新状态dp[bt][j]=now+getdis(p,a[j]);visit.find(a[j])->second=1;dfs(i+1, now+getdis(p,a[j]),bt,a[j]);visit.find(a[j])->second=0;}
/* for(int j=1; j<=n; j++){if(visit.find(a[j])->second)continue;if(now+getdis(p,a[j])>=bestv)continue;visit.find(a[j])->second=1;dfs(i+1, now+getdis(p,a[j]), a[j]);visit.find(a[j])->second=0;}*/
}/*不要被困在一种思路中
*/int main()
{//freopen("d://P1433_5.in","r",stdin);//freopen("d://out.txt","w",stdout);cin>>n;for(int i=1; i<=n; i++){cin>>a[i].first>>a[i].second;visit.insert(map<pair<double,double>,int>::value_type(a[i],0));}memset(dp,127,sizeof(dp));pair<double,double> t(0,0);dfs(0,0,0,t);printf("%.2lf",bestv);return 0;
}
Game of Ball Passing
看着挺简单的,就是不会。首先如果最大的数有两个及以上,那么一个球满足条件,根据此可以抽出最大的数maxx和剩余数的和sum,如果sum>=maxx,那么一定可以造出两个最大的数。如果小于那么肯定不满足,那么需要maxx-sum个球(此时一个球最多消耗maxx的sum+1)
#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
/*不要被困在一种思路中
*/
void solve(){long long n,a,maxx=-1,sum=0;cin>>n;for(int i=1; i<=n; i++){cin>>a;maxx=max(maxx,a);sum+=a;}sum-=maxx;if(sum >= maxx && sum!=0)cout<<1<<endl;else cout<<maxx-sum<<endl;
}int main()
{int t;cin>>t;while(t--)solve();return 0;
}
Cow Frisbee Team S
0-1背包,因为数据量的问题,需要运用求余小技巧。感觉如果使用一重数组,不论j从小到大还是从大到小,都会变成完全背包,归根结底还是对j取模的原因
#include <bits/stdc++.h>
#define eps 1e-15
#define mod 100000000
using namespace std;
/*不要被困在一种思路中
*/
//dp i j表示选第i头牛,队伍能力为对j取余,的方案数量
long long n,f,a[2005],dp[2005][1005];int main()
{//freopen("d://P2946_2.in","r",stdin);cin>>n>>f;for(int i=1; i<=n; i++)cin>>a[i];dp[0][f]=1;for(int i=1; i<=n; i++){for(int j=0; j<=f; j++){dp[i][j]+=dp[i-1][j];dp[i][(j+a[i])%f]=(dp[i][(j+a[i])%f]%mod+dp[i-1][j]%mod)%mod;}}cout<<dp[n][0]%mod;return 0;
}
质数和分解
完全背包
**#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
/*不要被困在一种思路中
*/
//dp j 表示选完第i个数,剩余数为j的方案数
int n,dp[205];bool judge(int x){if(x==1)return false;bool f=1;for(int i=2; i<=x/2; i++)if(x%i==0){f=0;break;}return f;
}void solve(){dp[n]=1;for(int i=2; i<=n; i++){if(!judge(i))continue;for(int j=n; j>=0; j--){if(j+i>n)continue;dp[j]+=dp[j+i];}}
}int main()
{while(scanf("%d",&n)!=EOF){solve();cout<<dp[0]<<endl;memset(dp,0,sizeof(dp));}return 0;
}**
Buying Hay S
完全背包
#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
/*不要被困在一种思路中
*/
//dp j表示j磅花费的价钱
int n,h,dp[55005],ans=0xfffffff;
pair<int, int> a[105];int main()
{cin>>n>>h;for(int i=1; i<=n; i++)cin>>a[i].first>>a[i].second;memset(dp,127,sizeof(dp));dp[0]=0;for(int i=1; i<=n; i++){for(int j=0; j<=h; j++){dp[j+a[i].first]=min(dp[j+a[i].first], dp[j]+a[i].second);}
/* for(int i=0; i<=h; i++)cout<<dp[i]<<" ";cout<<endl;*/}for(int i=h; i<=55004; i++)ans=min(ans,dp[i]);cout<<ans;return 0;
}
River Crossing S
0-1背包
#include <bits/stdc++.h>
#define eps 1e-15
using namespace std;
/*不要被困在一种思路中
*/
//dp i j表示运完第i头牛后,船上剩下的牛的数量
int dp[2505][2505],a[2505],n,m;
void solve(){int minn;dp[1][0]=m+a[1]+m;dp[1][1]=0;for(int i=2; i<=n; i++){dp[i][0]=dp[i-1][0]+m+a[1]+m;for(int j=1; j<=i-1; j++){//只需要计算每次运完后剩下0头牛的最小值,分为先运j头牛再运第i头牛和一起运j+1头牛dp[i][0]=min(min(dp[i-1][j]+a[j]+2*m+a[1]+2*m,dp[i-1][j]+a[j+1]+2*m),dp[i][0]);}for(int j=1; j<=i; j++)dp[i][j]=dp[i-1][j-1];}minn=dp[n][0]-m;for(int i=1; i<=n; i++)minn=min(dp[n][i]+a[i]+m,minn);cout<<minn;
}int main()
{cin>>n>>m;for(int i=1; i<=n; i++){cin>>a[i];a[i]+=a[i-1];}solve();return 0;
}
状态压缩+dfs+背包相关推荐
- 【hdu4281状态压缩+01背包+多旅行商问题】
题意:有n道题,每道题在二维平面内的不同位置且给出每道题的坐标,同时给出处理每道题所需的时间p,现在已知裁判的耐心有限,之会花费m个单位时间去做事,做完后回到起始点. 现在的要求是,我要多少个裁判才能 ...
- uva1507(状态压缩+dfs)
题意: 给出我们n种物品,每种物品都有五个值,分别是a.b.c.d.e,我们要在这n个物品中选出k个,使得这k个物品中的max{a}+max{b}+max{c}+max{d}+max{e}最大,输出最 ...
- OpenJudge - 海贼王之伟大航路(状态压缩+DFS)
题目链接:http://bailian.openjudge.cn/practice/4124?lang=en_US 总时间限制: 1000ms 内存限制: 65536kB 描述 "我是要成为 ...
- POJ2688状态压缩(可以+DFS剪枝)
题意: 给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路: 水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...
- 《算法竞赛进阶指南》打卡-基本算法-AcWing 94. 递归实现排列型枚举:dfs、二进制状态压缩
文章目录 题目解答 题目来源 题目解答 分析: dfs求全排列,这里是用二进制状态压缩进行优化,二进制状态压缩,顾名思义,每个状态是用二进制的某一位表示.这里的体现是state这个状态,它的每一位代表 ...
- 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩
文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...
- 《算法竞赛进阶指南》打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归、二进制状态压缩、dfs
文章目录 题目解答 题目链接 题目解答 分析: 优化:用二进制状态压缩,也就是用二进制上的位来记录数有没有被用过. ac代码 #include<bits/stdc++.h> using n ...
- hdu 3681(bfs+dfs+状态压缩)
解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑.这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说, ...
- CodeForces - 620E New Year Tree(线段树+dfs序+状态压缩)
题目链接:点击查看 题目大意:给出一棵无向树,每个节点都有一种颜色,接下来时m次操作: 1 x y:将x及其子树染成y的颜色 2 x:查询x及其子树上共有多少种不同的颜色 题目分析:看完这个题的第一反 ...
最新文章
- Wex5铛铛开发环境搭建步骤
- 图着色问题贪心算法c语言,区间图着色问题(贪心算法)C++实现
- qsort()与sort的用法(收藏)
- 微服务架构---幂等机制
- (二十五)【NIPS 2017】Prototypical Networks for Few-shot Learning
- Leetcode+牛客网—回文串总结(一)
- 多多自走棋服务器不稳定,多多自走棋突然宣布停服,数据将全部转移到腾讯服务器中...
- 华三路由器RIP协议详细配置
- [渝粤教育] 西南科技大学 语文教材教法 在线考试复习资料2021版
- 高德纳:盖茨亲自为他的书做推广
- Python3 计算空气质量指数AQI
- 深入理解SHA系列加密算法
- MEC与C-V2X融合应用场景白皮书
- 安卓物联网APP开发——基于编辑物联网平台环境实现远程控制数据传输
- PyTorch常用的张量创建、变形及运算总结(速查表)
- Classic BADI总结
- 全角半角符号引发的Entity Framework奇遇记
- Linux的rsa命令,openssl命令行进行RSA加密解密
- 全面认识Flash技术
- 韩称将强化对中国专属区内苏岩礁“警备”