A题:
发现n的范围只有20,所以暴力枚举每一个物品取或者不取,用二进制状态压缩来解决更加方便。
代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 返回总体积为V若干物品的最大总重量,如果g存在选择若干物品总体积为V的情况,返回-1
* @param v int整型vector
* @param g int整型vector
* @param V int整型
* @return int整型
*/
int Maximumweight(vector<int>& v, vector<int>& g, int V) {
int n=v.size(),ans=-1;
for(int i=0;i<(1<<n);i++){
int s=0,t=0;
for(int j=0;j<n;j++)
if(i>>j&1){
s=s+v[j];
t=t+g[j];
}
if(s==V)ans=max(ans,t);
}
return ans;
}
};时间复杂度 O(2^n)
B题:
最大前缀与最大后缀匹配,就是KMP中的next[len]的定义,所以直接套用模板即可。
代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 给定一个字符串s,返回具有相同前缀后缀的子串的第二大长度,反之,返回-1即可。
* @param s string字符串 代表题意中的字符串s
* @return int整型
*/
int nxt[1000010];
int solve(string s) {
int n=s.size();
s=" "+s;
for(int i=2,j=0;i<=n;i++){
while(j&&s[i]!=s[j+1])j=nxt[j];
if(s[i]==s[j+1])j++;
nxt[i]=j;
}
if(nxt[n]==0)return -1;
else return nxt[n];
}
};时间复杂度 O(n)
C题:
发现与普通的最短路不同,它的路程是乘起来的,所以中途可能会出现极大的数字但又不能取模。
所以,我们使用对数的一个性质log(a)+log(b)=log(a*b),讲乘法改为加法。
但是又有一个新的问题,long long的数值太小,无法预处理1000以内的组合数,但是我们有double啊,它的范围几乎刚刚包含1000以内最大的组合数,所以就用double存储,在跑最短路的同时,为了方便我们还可以同时记录最终的答案。
代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param n int整型 有n个城市
* @param m int整型 有m条路径
* @param s int整型 起始城市坐标
* @param t int整型 终点城市坐标
* @param edge int整型vector<vector<>> 边的格式如下:[[u1,v1,a1,b1],[u2,v2,a2,b2],...]
* @return int整型
*/
long long M=(1e9)+7,f[510][510],g[510][510],jc2[1010][1010],dis[510],dis2[510],vis[510];
double jc[1010][1010];
int minDist(int n, int m, int s, int t, vector<vector<int> >& edge) {
for(int i=0;i<=1000;i++){
jc[i][0]=1;
jc2[i][0]=1;
for(int j=1;j<=i;j++){
jc[i][j]=jc[i-1][j]+jc[i-1][j-1];
jc2[i][j]=(jc2[i-1][j]+jc2[i-1][j-1])%M;
}
}
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)f[i][i]=0;
for(int i=0;i<m;i++){
int u=edge[i][0],v=edge[i][1],a=edge[i][2],b=edge[i][3];
f[u][v]=f[v][u]=log(jc[a][b]);
g[u][v]=g[v][u]=jc2[a][b];
}
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
dis2[s]=1;
for(int i=1;i<=n;i++){
int nw=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]<dis[nw])nw=j;
vis[nw]=true;
if(nw==t)break;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[nw]+f[nw][j]<dis[j]){
dis[j]=dis[nw]+f[nw][j];
dis2[j]=dis2[nw]*g[nw][j]%M;
}
}
return dis2[t];
}
};时间复杂度 O(n^2)

京公网安备 11010502036488号