三国赵云传纵横天下2纵横天下背包问题

相关资讯:
类似网站: 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
《三国赵云传之纵横天下》----提前炼出终极装备的讲解之二
下载积分:30
内容提示:《三国赵云传之纵横天下》----提前炼出终极装备的讲解之二
文档格式:PDF|
浏览次数:294|
上传日期: 03:29:51|
文档星级:
该用户还上传了这些文档
《三国赵云传之纵横天下》----提前炼出终极装备的讲解之二
官方公共微信三国赵云传2纵横天下为什么存档可一读档就是遇到问题需要关闭类?_百度知道&《赵云传一》的物品复制法,就是把东西丢在地上,然后alt+tab出去修改/save/game目录下的good.dat文件属性为只读,进游戏,存档,再alt+tab出去把good.dat的只读属性改回去。回去后读刚才存的那个档,会发现刚才扔掉的东西身上有一份,地上也有一份。我没玩过《赵云传一》,无从实验,不知道这个方法在一代中行不行,不过《纵横天下》用此法不能复制。因为可能一代中good.dat这个文件只是身上的物品信息,而地上的物品在另一个文件中,所以可以复制。而显然《纵横天下》去掉了这个bug,good.dat文件包含了所有的物品信息,身上和地上的。
虽然前面提到的方法不可以复制,但是却让我发现了《三国赵云传2:纵横天下》的存档和读档方式。二代和一代(关于本文提及所有关于一代的情况,都属推测,因为偶没玩过的说)一样,存档的时候先把当前的所有信息分开存到/save/game/目录下的个个文件中,然后统一把再把这个目录下的文件结合在一起存到/save/s*/save*.dat文件中(有点像压缩,*代表你1-7任意一个数字,比如你存的是第一个档,这里的就是save1.dat)。注意,这里有个关键,save*.dat文件是由/save/game/下的文件存过来的,而不是直接由游戏存。我就是利用这一点来完成时空传送和复制。读档的时候,反过来,把save*.dat中的信息分开存到/save/game/中,(有点像解压)。/save/game这个目录在退出游戏的时候会被删除。这里也有一点是要注意的,在读档的时候由于同时要/save/game中存一次档,所以必须保证/save/game下的文件不存在或者可写,如果是只读的话就会发生错误。
聪明的朋友应该已经想到我的方法了。前面提过good.dat文件是包括所有物品信息的。比如你现在有一个最终终极装备存档,一个初始存档,你想把终极装备转移到初始存档中,只要读取最终存档,然后把/save/game/目录下的good.dat文件copy出来,然后读取初始存档,把刚才copy出来的good.dat文件copy回去,并且属性改为只读,切换回游戏,存档,最后在读档前别忘了把good.dat的只读属性去掉。这样就完成了任意2个不同时空的装备传送。游戏中有2个特殊地点,一个是白帝城救刘备前的军营中,有个铁匠可以无限购买紫水晶,龙鳞和凤羽。另一个是白帝城中有个奸商可以复制物品。所以你要分别准备这两个的存档。比如你在某个时候想要复制,就先用时空转移法把所有物品都转移到白帝城中,复制完存个档再转移回去就OK了。
三国赵云传2:纵横天下好玩吗? []
相关游戏攻略:
相关资源下载:
[游戏大小:891 MB ]10625人阅读
有n 种不同的物品,每个物品有两个属性,size 体积,value 价值,现在给一个容量为 w 的背包,问最多可带走多少价值的物品。
int f[w+1];
//f[x] 表示背包容量为x 时的最大价值
for (int i=0; i&n; i++)
for (int j=w; j&=size[i]; j--)
f[j] = max(f[j], f[j-size[i]]+value[i]);
如果物品不计件数,就是每个物品不只一件的话,稍微改下即可 &
for (int i=0; i&n; i++)
for (int j=size[i]; j&=w; j++)
f[j] = max(f[j], f[j-size[i]]+value[i]);
& & & &&f[w] 即为所求 &
&&&&&&& 初始化分两种情况:
&&&&&&& 1、如果背包要求正好装满则初始化 f[0] = 0, f[1~w] = -INF; &
&&&&&&& 2、如果不需要正好装满 f[0~v] = 0; &
& & & & 举例:
V=10,N=3,c[]={3,4,5}, w={4,5,6}
(1)背包不一定装满
& & & 计算顺序是:从右往左,自上而下:因为每个物品只能放一次,前面的体积小的会影响体积大的
(2)背包刚好装满 & &
& & & 计算顺序是:从右往左,自上而下。注意初始值,其中-inf表示负无穷
完全背包:
V=10,N=3,c[]={3,4,5}, w={4,5,6}
(1)背包不一定装满
计算顺序是:从左往右,自上而下: &每个物品可以放多次,前面的会影响后面的
(2)背包刚好装满
计算顺序是:从左往右,自上而下。注意初始值,其中-inf表示负无穷
多重背包: &
& & & & &多重背包问题要求很简单,就是每件物品给出确定的件数,求可得到的最大价值 &
& & & & &多重背包转换成 01 背包问题就是多了个初始化,把它的件数C 用二进制***成若干个件数的集合,这里面数字可以组合成任意小于等于C的件数,而且不会重复,之所以叫二进制***,是因为这样***可以用数字的二进制形式来解释
& & & &比如:7的二进制 7 = 111 它可以***成 001 010 100 这三个数可以组合成任意小于等于7 的数,而且每种组合都会得到不同的数
& & & &15 = 1111 可***成 &
四个数字 &
&&&&&&& 如果13 = 1101 则***为 00 0110 前三个数字可以组合成 &7以内任意一个数,即1、2、4可以组合为1----7内所有的数,加上
0110 = 6 可以组合成任意一个大于6 小于等于13的数,比如12,可以让前面贡献6且后面也贡献6就行了。虽然有重复但总是能把 13 以内所有的数都考虑到了,基于这种思想去把多件物品转换为,多种一件物品,就可用01
背包求解了。 &
&&&& & 看代码: &
//输入有多少种物品
//每种物品有多少件
//每种物品的价值
//每种物品的尺寸
int count = 0; //***后可得到多少种物品
int value[MAX]; //用来保存***后的物品价值
int size[MAX];
//用来保存***后物品体积
scanf(&%d&, &n);
//先输入有多少种物品,接下来对每种物品进行***
while (n--)
//接下来输入n中这个物品
scanf(&%d%d%d&, &c, &s, &v);
//输入每种物品的数目和价值
for (int k=1; k&=c; k&&=1)
//&&右移 相当于乘二
value[count] = k*v;
size[count++] = k*s;
if (c & 0)
value[count] = c*v;
size[count++] = c*s;
定理:一个正整数n可以被***成1,2,4,…,2^(k-1),n-2^k+1(k是满足n-2^k+1&0的最大整数)的形式,且1~n之内的所有整数均可以唯一表示成1,2,4,…,2^(k-1),n-2^k+1中某几个数的和的形式。
证明如下:
(1) 数列1,2,4,…,2^(k-1),n-2^k+1中所有元素的和为n,所以若干元素的和的范围为:[1, n];
(2)如果正整数t&= 2^k - 1,则t一定能用1,2,4,…,2^(k-1)中某几个数的和表示,这个很容易证明:我们把t的二进制表示写出来,很明显,t可以表示成n=a0*2^0+a1*2^1+…+ak*2^(k-1),其中ak=0或者1,表示t的第ak位二进制数为0或者1.
(3)如果t&=2^k,设s=n-2^k+1,则t-s&=2^k-1,因而t-s可以表示成1,2,4,…,2^(k-1)中某几个数的和的形式,进而t可以表示成1,2,4,…,2^(k-1),s中某几个数的和(加数中一定含有s)的形式。
(证毕!)
&&&&&&& 现在用count 代替 n 就和01 背包问题完全一样了&&
杭电2191题解:此为多重背包用01和完全背包:
#include&stdio.h&
#include&string.h&
int dp[102];
int p[102],h[102],c[102];
void comback(int v,int w)//经费,重量。完全背包;
for(int i=v; i&=n; i++)
if(dp[i]&dp[i-v]+w)
dp[i]=dp[i-v]+w;
void oneback(int v,int w)//经费,重量;01背包;
for(int i=n; i&=v; i--)
if(dp[i]&dp[i-v]+w)
dp[i]=dp[i-v]+w;
int main()
int ncase,i,j,k;
scanf(&%d&,&ncase);
while(ncase--)
memset(dp,0,sizeof(dp));
scanf(&%d%d&,&n,&m);//经费,种类;
for(i=1; i&=m; i++)
scanf(&%d%d%d&,&p[i],&h[i],&c[i]);//价值,重量,数量;
if(p[i]*c[i]&=n) comback(p[i],h[i]);
for(j=1; j&c[i]; j&&1)
oneback(j*p[i],j*h[i]);
c[i]=c[i]-j;
oneback(p[i]*c[i],h[i]*c[i]);
printf(&%d\n&,dp[n]);
只是用01背包,用二进制优化:
#include &iostream&
int main()
int nCase,Limit,nKind,i,j,k,
v[111],w[111],c[111],dp[111];
//v[]存价值,w[]存尺寸,c[]存件数
//在本题中,价值是米的重量,尺寸是米的价格
int count,Value[1111],size[1111];
//count存储***完后的物品总数
//Value存储***完后每件物品的价值
//size存储***完后每件物品的尺寸
while(nCase--)
cin&&Limit&&nK
for(i=0; i&nK i++)
cin&&w[i]&&v[i]&&c[i];
//对该种类的c[i]件物品进行二进制***
for(j=1; j&=c[i]; j&&=1)
//&&左移1位,相当于乘2
Value[count]=j*v[i];
size[count++]=j*w[i];
if(c[i]&0)
Value[count]=c[i]*v[i];
size[count++]=c[i]*w[i];
//经过上面对每一种物品的***,
//现在Value[]存的就是***后的物品价值
//size[]存的就是***后的物品尺寸
//count就相当于原来的n
//下面就直接用01背包算法来解
memset(dp,0,sizeof(dp));
for(i=0; i& i++)
for(j=L j&=size[i]; j--)
if(dp[j]&dp[j-size[i]]+Value[i])
dp[j]=dp[j-size[i]]+Value[i];
cout&&dp[Limit]&&
未优化的:
#include&iostream&
#include&cstdio&
#include&cstring&
int Value[105];
int Cost[105];
int Bag[105];
int dp[105];
int main()
int C,m,n;
scanf(&%d&,&C);
while(C--)
scanf(&%d%d&,&n,&m);
for(int i = 1; i &= i++)
scanf(&%d%d%d&,&Cost[i],&Value[i],&Bag[i]);
memset(dp,0,sizeof(dp));
for(int i=1; i&= i++)
for(int j=1; j&=Bag[i]; j++)
for(int k=n; k&=Cost[i]; k--)
dp[k]=max(dp[k], dp[k-Cost[i]]+Value[i]);
printf(&%d\n&,dp[n]);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:390749次
积分:7073
积分:7073
排名:第2239名
原创:316篇
评论:68条
(3)(3)(1)(3)(1)(1)(2)(12)(10)(17)(12)(35)(20)(1)(4)(31)(14)(16)(10)(1)(7)(6)(3)(9)(25)(5)(15)(30)(7)(1)(12)

参考资料

 

随机推荐