【洛谷P1361】小猫爬山
来源:互联网 发布:mysql已删除的表 编辑:程序博客网 时间:2024/04/19 15:12
【简单题,请神犇移步】
某知dealpool66告诉我可以用这道题练习模拟退火。
然后我一眼看过去不是贪心吗。。
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;#define N 28int n,w,a[N];int ans = 0;bool vis[N],flag;bool cmp(const int x,const int y){return x>y;}void dfs(int u,int res){ if(!res)return; for(int i=u;i<=n;i++)if(!vis[i]) { if(res>=a[i]) { vis[i]=true; dfs(i,res-a[i]); } } }int main(){ cin>>n>>w; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { if(!vis[i]) { ++ans;vis[i]=true; dfs(i+1,w-a[i]); } } cout<<ans; return 0;}
然后就24分了orz。
诶,我感觉贪心思路是对的。。只是直接写要错。。
因为如果刚好能凑满的话直接贪就错了。
啊,于是乎,我开始感觉难实现,然后想了想,发现dfs返回个bool就可以了。
然后。。
代码如下:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;#define N 28int n,w,a[N];int ans = 0;bool vis[N];bool cmp(const int x,const int y){return x>y;}bool dfs(int u,int res){ if(!res)return true; bool flag = false; for(int i=u;i<=n;i++)if(!vis[i]) { if(res>=a[i]) { vis[i]=true; flag=dfs(i+1,res-a[i]); if(flag)break; vis[i]=false; } } if(flag)return true; for(int i=u;i<=n;i++) { if(a[i]<=res) { vis[i]=true; dfs(i+1,res-a[i]); break; } } return false;}int main(){ cin>>n>>w; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { if(!vis[i]) { ++ans;vis[i]=true; dfs(i+1,w-a[i]); } } cout<<ans; return 0;}
和开始的代码的区别是,判断后面有没有刚好组成w的方案,如果有肯定这种最优,否则,我们就尽量先消除大的。
然后 75分。
数据生成器:
#!usr/bin/env python#-*- coding:utf-8 -*-import randomimport sysfp = open("in.in","w")sys.stdout = fpn = random.randint(1,18)m = random.randint(1,10000000)#print >>fp,n#print >>fp,mprint nprint mfor i in range(1,n+1): #print >>fp,random.randint(1,m) print random.randint(1,m)
然后QWQ我知道我错了。
但是好像很不容易卡。。
对拍了半天。。
模拟退火
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<iostream>#include<ctime>using namespace std;int n,w,rpath[1000][20],ans[1000],a[20];void adjust(int *p,int rn){ while(rn--) { int x=rand()%n+1; int y=rand()%n+1; swap(p[x],p[y]); }}void get_rpath(){ for(int i=0;i<1000;i++) { ans[i]=1e9; for(int j=1;j<=n;j++)rpath[i][j]=j; adjust(rpath[i],n-1); }}int get_val(int *p){ int ret=0,sum=0; for(int i=1;i<=n;i++) { sum+=a[p[i]]; if(sum>w){ret++;sum=a[p[i]];} } if(sum)ret++; return ret;}int main(){ freopen("koneko.in","r",stdin);freopen("koneko.out","w",stdout); srand(time(NULL)); scanf("%d%d",&n,&w); for(int i=1;i<=n;i++)scanf("%d",&a[i]); get_rpath(); int t=n,p[20]; while(t--) { for(int i=0;i<1000;i++) { for(int j=0;j<50;j++) { memcpy(p,rpath[i],sizeof(p)); adjust(p,t); int tmp=get_val(p); if(tmp<ans[i]) { ans[i]=tmp; memcpy(rpath[i],p,sizeof(rpath[i])); } } } } int res=ans[0]; for(int i=1;i<1000;i++)res=min(res,ans[i]); cout<<res<<endl; return 0;}
正解迭代加深
#include<iostream>#include<cstdio>using namespace std;const int size = 24;int w[size];int z[size];int n,k;bool flag;void dfs(int s,int u){ if(flag) return ; if(u > n) { flag = 1; return ; } int mx = min(s,u); for(int i = 1 ; i <= mx ; i ++) { if(z[i] + w[u] > k) continue; z[i] += w[u]; dfs(s,u+1); z[i] -= w[u]; }}int main(){ scanf("%d%d",&n,&k); for(int i = 1 ; i <= n ; i ++) scanf("%d",&w[i]); for(int i = 1 ; i <= n ; i ++) { dfs(i,1); if(flag) { printf("%d\n",i); break; } } return 0;}
1 0
- 洛谷 P1361 小猫爬山
- 【洛谷P1361】小猫爬山
- 洛谷 P1361 小猫爬山
- P1361 小猫爬山 bool dfs
- 小猫爬山
- TYVJ2018 小猫爬山
- 【NOIP2013模拟】小猫爬山
- 状压动规:BSOJ3805 小猫爬山
- TYVJ 2018 小猫爬山
- 【tyvj】【搜索】小猫爬山
- 小猫爬山 搜索 先放大的
- 二分答案+DFS验证 小猫爬山
- TYVJ P2018 「Nescafé26」小猫爬山
- BSOJ3805 codevs4228 tyvj2018 【NOIP模拟赛】小猫爬山
- tyvj P2018 「Nescafé26」小猫爬山
- Tyvj P2018 「Nescafé26」小猫爬山
- 爬山
- 爬山
- 正则表达式(二)
- Ubuntu 更换软件源方法汇总
- odoo api装饰器使用
- Android基础(一)
- Python set
- 【洛谷P1361】小猫爬山
- 洛谷 P1495 曹冲养猪
- RSA加密解密及数字签名Java实现
- handlePollCalls方法详解
- 真正实现多点结构总线的是?
- ACM算法---常数和语言基础
- C++:stringstream
- C 交叉存放字符串
- hdu 5950 矩阵加速递推