提交 b16d5a66 编写于 作者: qq_36480062's avatar qq_36480062

commit

上级 e68a17fc
......@@ -2,8 +2,9 @@ package com.shiyu;
public class tsdt {
public static void main(String[] args) {
for (int i = 0; i < 4; i++) {
System.out.println(i);
int i = 0;
for (i = 4; i >= 3; i--) {
}
System.out.println(i);
}
}
......@@ -7,9 +7,10 @@ import java.util.Arrays;
*/
public class bag {
public static void main(String[] args) {
System.out.println(dp());
System.out.println();
System.out.println(dpByOne());
// w(3);
// System.out.println(dp());
// System.out.println();
System.out.println(dpByWan());
}
public static int n = 4;//物品数量
......@@ -111,6 +112,17 @@ public class bag {
}
public static void DpbyWan() {
}
public static void w(int n) {
int c[] = {1, 2, 3};
int dp[] = new int[n + 1];
for (int i =1; i <= n; i++) {
for (int j =0; j < 3; j++) {
dp[j] = dp[j] + dp[j - c[i]];
}
}
System.out.println(dp[n]);
}
}
package dp;
import java.util.Scanner;
/**
* 搬寝室
* 搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆,因为n是一个小于2000的整数,实在是太多了,于是xhd决定随便搬2*k件过去就行了.但还是会很累,因为2*k也不小是一个不大于n的整数.幸运的是xhd根据多年的搬东西的经验发现每搬一次的疲劳度是和左右手的物品的重量差的平方成正比(这里补充一句,xhd每次搬两件东西,左手一件右手一件).例如xhd左手拿重量为3的物品,右手拿重量为6的物品,则他搬完这次的疲劳度为(6-3)^2 = 9.现在可怜的xhd希望知道搬完这2*k件物品后的最佳状态是怎样的(也就是最低的疲劳度),请告诉他吧.
* Input
* 每组输入数据有两行,第一行有两个数n,k(2<=2*k<=n<2000).第二行有n个整数分别表示n件物品的重量(重量是一个小于2^15的正整数).
* Output
* 对应每组输入数据,输出数据只有一个表示他的最少的疲劳度,每个一行.
* Sample Input
* 2 1
* 1 3
* Sample Output
* 4
*/
public class 搬寝室 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
for (int i = 0; i < k; i++) {
}
}
}
package dp;
import java.util.Arrays;
import java.util.Scanner;
/**
* 某条街上每一公里就有一汽车站,乘车费用如下表:
* 公里数 1 2 3 4 5 6 7 8 9 10
* 费用 12 21 31 40 49 58 69 79 90 101
* 而一辆汽车从不行驶超过10公里。
* 某人想行驶n公里,假设他可以任意次换车,请你帮他找到一种乘车方案使费用最小(10公里的费用比1公里小的情况是允许的)。
* Sample Input
* 12 21 31 40 49 58 69 79 90 101 1-10公里的费用
* 15
* Sample Output
* 147
*/
public class 最小乘车费用 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int gongli[] = new int[11];
for (int i = 1; i <= 10; i++) {
gongli[i] = sc.nextInt();
}
int[] dp = Arrays.copyOf(gongli, 1001);
Arrays.fill(dp, 11, dp.length, Integer.MAX_VALUE);
int n = sc.nextInt();
for (int i = 1; i <= n; i++) {//n是要行驶公里
for (int j = 10; j >= 1; j--) {
if (i >= j) {
dp[i] = Math.min(dp[i], dp[i - j] + gongli[j]);
}
}
}
System.out.println(dp[n]);
}
}
package dp;
import java.util.Scanner;
/**
* 装箱问题(弱01背包问题,水题)
* 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
* 要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
* 输入描述 Input Description
* 一个整数v,表示箱子容量
* 一个整数n,表示有n个物品
* 接下来n个整数,分别表示这n 个物品的各自体积
* 输出描述 Output Description
* 一个整数,表示箱子剩余空间。
* 样例输入 Sample Input
* 24
* 6
* 8
* 3
* 12
* 7
* 9
* 7
* 样例输出 Sample Output
* 0
*/
public class 装箱问题 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int v = sc.nextInt();//箱子容量
int n = sc.nextInt();//物品数量
int tiji[] = new int[n + 1];
for (int i = 1; i <= n; i++) {
tiji[i] = sc.nextInt();
}
int dp[][] = new int[30][20004];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= v; j++) {
if (tiji[i] <= j) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - tiji[i]] + tiji[i]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
System.out.println(dp[n][v]);
}
}
......@@ -166,14 +166,14 @@ public class 做作业 {
if (!do_work1[list.get(j).day]) {
do_work1[list.get(j).day] = true;
} else {
for (k = list.get(j).day; k >= 1; k--) {
for (k = list.get(j).day; k >= 1; k--) {//因为相同日期的作业中,分数高的会在前面,如果找不到,没有执行到break,k的值为0,就会把其+=ans
if (!do_work1[k])
break;
}//往前找,找到没有占用的那一天的索引下标,就是k
if (k > 0) {//对找到的k进行合法性判断,没有第0天
do_work1[k] = true;
} else {
ans += list.get(j).score;
ans += list.get(j).score;//题目说求被扣的最小分数,意思是,最终被放弃做的作业的分数之和
}
}
}
......
......@@ -9,3 +9,5 @@
1.分解(Divide): 将原问题分解成一系列子问题
2.解决(Conquer): 递归地解决每个子问题,若子问题足够小,则直接有解
3.合并(Combine): 将子问题的结果合并成原问题的解
将原问题划分为互不相交的子问题,递归的求解子问题,再将它们的解组合起来
\ No newline at end of file
###动态规划
###动态规划(打表)
```
动态规划,在子问题重叠的情况,不同的子问题具有公共的子子问题
动态规划需要具备最优子结构,重叠子问题
基本条件:开始动态规划的,初值,起始条件
边界:问题的边界,得到有限的结果
动态转移方程(dp方程):问题的每一阶段和下一阶段的关系
问题中的状态必须满足无后效性,以前出现状态和以前状态变化,不会影响将来的变化
动态规划:当前问题的最优解,不能从上一阶段子问题简单得出,需要前面多阶段
多阶层子问题共同计算出,因此需要保存历史求解过的子问题,及其最优解
......@@ -28,6 +35,11 @@ W=5
w = {2, 1, 3, 2};//重量
v = {3, 2, 4, 2};//价值
1.1 完全背包
N件物品,容量为W的背包,第i件物品重量为Wi,价值为Vi,每件物品有无数个,求装的最大价值
dp[i,j]=max[dp[i,j],dp[i-1,j-k*Wi]+k*Vi] (k>=0)
2.钢条切割
Serling公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。
假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元)。钢条的长度均为整英寸。
......@@ -65,4 +77,13 @@ Serling公司购买长钢条,将其切割为短钢条出售。切割工序本
dp[0][0]就是最大值
从倒数第二排开始打表,
还可以使用滚动数组,一维数组
\ No newline at end of file
还可以使用滚动数组,一维数组
3.有n个石子,A,B轮流取石子,最少一个最多两个,取最后一个的人赢
F[i]代表当前状态还剩多少石子,
F[0]=0 0代表后手赢,因为先手去取石子,石子没有了,代表后手已经石子取完了
F[1]/F[2]=1 这个状态,1代表先手赢,因为他可以取完,谁先手谁赢
对于F[i]来说,能不能让F[i-1]F[i-2]变成一个输的状态,(使F[i-1]=0,F[i-2]=0)
不关心状态是怎么来的,只关心它现在这个状态
假设有20个石子,你拿到20个的时候赢,你需要让对面拿完剩18个,或者19个,你自己就赢了
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册